123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>The source code</title>
- <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
- <style type="text/css">
- .highlight { display: block; background-color: #ddd; }
- </style>
- <script type="text/javascript">
- function highlight() {
- document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
- }
- </script>
- </head>
- <body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-layout-container-CheckboxGroup'>/**
- </span> * This layout implements the column arrangement for {@link Ext.form.CheckboxGroup} and {@link Ext.form.RadioGroup}.
- * It groups the component's sub-items into columns based on the component's
- * {@link Ext.form.CheckboxGroup#columns columns} and {@link Ext.form.CheckboxGroup#vertical} config properties.
- */
- Ext.define('Ext.layout.container.CheckboxGroup', {
- extend: 'Ext.layout.container.Container',
- alias: ['layout.checkboxgroup'],
- <span id='Ext-layout-container-CheckboxGroup-cfg-autoFlex'> /**
- </span> * @cfg {Boolean} [autoFlex=true]
- * By default, CheckboxGroup allocates all available space to the configured columns meaning that
- * column are evenly spaced across the container.
- *
- * To have each column only be wide enough to fit the container Checkboxes (or Radios), set `autoFlex` to `false`
- */
- autoFlex: true,
- type: 'checkboxgroup',
- childEls: [
- 'innerCt'
- ],
- renderTpl: [
- '<table id="{ownerId}-innerCt" role="presentation" style="{tableStyle}"><tbody><tr>',
- '<tpl for="columns">',
- '<td class="{parent.colCls}" valign="top" style="{style}">',
- '{% this.renderColumn(out,parent,xindex-1) %}',
- '</td>',
- '</tpl>',
- '</tr></tbody></table>'
- ],
- lastOwnerItemsGeneration : null,
- beginLayout: function(ownerContext) {
- var me = this,
- columns,
- numCols,
- i, width, cwidth,
- totalFlex = 0, flexedCols = 0,
- autoFlex = me.autoFlex,
- innerCtStyle = me.innerCt.dom.style;
- me.callParent(arguments);
- columns = me.columnNodes;
- ownerContext.innerCtContext = ownerContext.getEl('innerCt', me);
- // The columns config may be an array of widths. Any value < 1 is taken to be a fraction:
- if (!ownerContext.widthModel.shrinkWrap) {
- numCols = columns.length;
- // If columns is an array of numeric widths
- if (me.columnsArray) {
- // first calculate total flex
- for (i = 0; i < numCols; i++) {
- width = me.owner.columns[i];
- if (width < 1) {
- totalFlex += width;
- flexedCols++;
- }
- }
- // now apply widths
- for (i = 0; i < numCols; i++) {
- width = me.owner.columns[i];
- if (width < 1) {
- cwidth = ((width / totalFlex) * 100) + '%';
- } else {
- cwidth = width + 'px';
- }
- columns[i].style.width = cwidth;
- }
- }
- // Otherwise it's the *number* of columns, so distributed the widths evenly
- else {
- for (i = 0; i < numCols; i++) {
- // autoFlex: true will automatically calculate % widths
- // autoFlex: false allows the table to decide (shrinkWrap, in effect)
- // on a per-column basis
- cwidth = autoFlex
- ? (1 / numCols * 100) + '%'
- : '';
- columns[i].style.width = cwidth;
- flexedCols++;
- }
- }
- // no flexed cols -- all widths are fixed
- if (!flexedCols) {
- innerCtStyle.tableLayout = 'fixed';
- innerCtStyle.width = '';
- // some flexed cols -- need to fix some
- } else if (flexedCols < numCols) {
- innerCtStyle.tableLayout = 'fixed';
- innerCtStyle.width = '100%';
- // let the table decide
- } else {
- innerCtStyle.tableLayout = 'auto';
- // if autoFlex, fill available space, else compact down
- if (autoFlex) {
- innerCtStyle.width = '100%';
- } else {
- innerCtStyle.width = '';
- }
- }
- } else {
- innerCtStyle.tableLayout = 'auto';
- innerCtStyle.width = '';
- }
- },
- cacheElements: function () {
- var me = this;
- // Grab defined childEls
- me.callParent();
- me.rowEl = me.innerCt.down('tr');
- // Grab columns TDs
- me.columnNodes = me.rowEl.dom.childNodes;
- },
- /*
- * Just wait for the child items to all lay themselves out in the width we are configured
- * to make available to them. Then we can measure our height.
- */
- calculate: function(ownerContext) {
- var me = this,
- targetContext, widthShrinkWrap, heightShrinkWrap, shrinkWrap, table, targetPadding;
- // The columnNodes are widthed using their own width attributes, we just need to wait
- // for all children to have arranged themselves in that width, and then collect our height.
- if (!ownerContext.getDomProp('containerChildrenDone')) {
- me.done = false;
- } else {
- targetContext = ownerContext.innerCtContext;
- widthShrinkWrap = ownerContext.widthModel.shrinkWrap;
- heightShrinkWrap = ownerContext.heightModel.shrinkWrap;
- shrinkWrap = heightShrinkWrap || widthShrinkWrap;
- table = targetContext.el.dom;
- targetPadding = shrinkWrap && targetContext.getPaddingInfo();
- if (widthShrinkWrap) {
- ownerContext.setContentWidth(table.offsetWidth + targetPadding.width, true);
- }
- if (heightShrinkWrap) {
- ownerContext.setContentHeight(table.offsetHeight + targetPadding.height, true);
- }
- }
- },
- doRenderColumn: function (out, renderData, columnIndex) {
- // Careful! This method is bolted on to the renderTpl so all we get for context is
- // the renderData! The "this" pointer is the renderTpl instance!
- var me = renderData.$layout,
- owner = me.owner,
- columnCount = renderData.columnCount,
- items = owner.items.items,
- itemCount = items.length,
- item, itemIndex, rowCount, increment, tree;
- // Example:
- // columnCount = 3
- // items.length = 10
- if (owner.vertical) {
- // 0 1 2
- // +---+---+---+
- // 0 | 0 | 4 | 8 |
- // +---+---+---+
- // 1 | 1 | 5 | 9 |
- // +---+---+---+
- // 2 | 2 | 6 | |
- // +---+---+---+
- // 3 | 3 | 7 | |
- // +---+---+---+
- rowCount = Math.ceil(itemCount / columnCount); // = 4
- itemIndex = columnIndex * rowCount;
- itemCount = Math.min(itemCount, itemIndex + rowCount);
- increment = 1;
- } else {
- // 0 1 2
- // +---+---+---+
- // 0 | 0 | 1 | 2 |
- // +---+---+---+
- // 1 | 3 | 4 | 5 |
- // +---+---+---+
- // 2 | 6 | 7 | 8 |
- // +---+---+---+
- // 3 | 9 | | |
- // +---+---+---+
- itemIndex = columnIndex;
- increment = columnCount;
- }
- for ( ; itemIndex < itemCount; itemIndex += increment) {
- item = items[itemIndex];
- me.configureItem(item);
- tree = item.getRenderTree();
- Ext.DomHelper.generateMarkup(tree, out);
- }
- },
- <span id='Ext-layout-container-CheckboxGroup-method-getColumnCount'> /**
- </span> * Returns the number of columns in the checkbox group.
- * @private
- */
- getColumnCount: function() {
- var me = this,
- owner = me.owner,
- ownerColumns = owner.columns;
- // Our columns config is an array of numeric widths.
- // Calculate our total width
- if (me.columnsArray) {
- return ownerColumns.length;
- }
- if (Ext.isNumber(ownerColumns)) {
- return ownerColumns;
- }
- return owner.items.length;
- },
- getItemSizePolicy: function (item) {
- return this.autoSizePolicy;
- },
- getRenderData: function () {
- var me = this,
- data = me.callParent(),
- owner = me.owner,
- i, columns = me.getColumnCount(),
- width, column, cwidth,
- autoFlex = me.autoFlex,
- totalFlex = 0, flexedCols = 0;
- // calculate total flex
- if (me.columnsArray) {
- for (i=0; i < columns; i++) {
- width = me.owner.columns[i];
- if (width < 1) {
- totalFlex += width;
- flexedCols++;
- }
- }
- }
- data.colCls = owner.groupCls;
- data.columnCount = columns;
- data.columns = [];
- for (i = 0; i < columns; i++) {
- column = (data.columns[i] = {});
- if (me.columnsArray) {
- width = me.owner.columns[i];
- if (width < 1) {
- cwidth = ((width / totalFlex) * 100) + '%';
- } else {
- cwidth = width + 'px';
- }
- column.style = 'width:' + cwidth;
- } else {
- column.style = 'width:' + (1 / columns * 100) + '%';
- flexedCols++;
- }
- }
- // If the columns config was an array of column widths, allow table to auto width
- data.tableStyle =
- !flexedCols ? 'table-layout:fixed;' :
- (flexedCols < columns) ? 'table-layout:fixed;width:100%' :
- (autoFlex) ? 'table-layout:auto;width:100%' : 'table-layout:auto;';
- return data;
- },
- initLayout: function () {
- var me = this,
- owner = me.owner;
- me.columnsArray = Ext.isArray(owner.columns);
- me.autoColumns = !owner.columns || owner.columns === 'auto';
- me.vertical = owner.vertical;
- me.callParent();
- },
- // Always valid. beginLayout ensures the encapsulating elements of all children are in the correct place
- isValidParent: function() {
- return true;
- },
- setupRenderTpl: function (renderTpl) {
- this.callParent(arguments);
- renderTpl.renderColumn = this.doRenderColumn;
- },
- renderChildren: function () {
- var me = this,
- generation = me.owner.items.generation;
- if (me.lastOwnerItemsGeneration !== generation) {
- me.lastOwnerItemsGeneration = generation;
- me.renderItems(me.getLayoutItems());
- }
- },
- <span id='Ext-layout-container-CheckboxGroup-method-renderItems'> /**
- </span> * Iterates over all passed items, ensuring they are rendered. If the items are already rendered,
- * also determines if the items are in the proper place in the dom.
- * @protected
- */
- renderItems : function(items) {
- var me = this,
- itemCount = items.length,
- i,
- item,
- rowCount,
- columnCount,
- rowIndex,
- columnIndex;
- if (itemCount) {
- Ext.suspendLayouts();
- if (me.autoColumns) {
- me.addMissingColumns(itemCount);
- }
- columnCount = me.columnNodes.length;
- rowCount = Math.ceil(itemCount / columnCount);
- for (i = 0; i < itemCount; i++) {
- item = items[i];
- rowIndex = me.getRenderRowIndex(i, rowCount, columnCount);
- columnIndex = me.getRenderColumnIndex(i, rowCount, columnCount);
- if (!item.rendered) {
- me.renderItem(item, rowIndex, columnIndex);
- } else if (!me.isItemAtPosition(item, rowIndex, columnIndex)) {
- me.moveItem(item, rowIndex, columnIndex);
- }
- }
- if (me.autoColumns) {
- me.removeExceedingColumns(itemCount);
- }
- Ext.resumeLayouts(true);
- }
- },
- isItemAtPosition : function(item, rowIndex, columnIndex) {
- return item.el.dom === this.getNodeAt(rowIndex, columnIndex);
- },
- getRenderColumnIndex : function(itemIndex, rowCount, columnCount) {
- if (this.vertical) {
- return Math.floor(itemIndex / rowCount);
- } else {
- return itemIndex % columnCount;
- }
- },
- getRenderRowIndex : function(itemIndex, rowCount, columnCount) {
- var me = this;
- if (me.vertical) {
- return itemIndex % rowCount;
- } else {
- return Math.floor(itemIndex / columnCount);
- }
- },
- getNodeAt : function(rowIndex, columnIndex) {
- return this.columnNodes[columnIndex].childNodes[rowIndex];
- },
- addMissingColumns : function(itemsCount) {
- var me = this,
- existingColumnsCount = me.columnNodes.length,
- missingColumnsCount,
- row,
- cls,
- i;
- if (existingColumnsCount < itemsCount) {
- missingColumnsCount = itemsCount - existingColumnsCount;
- row = me.rowEl;
- cls = me.owner.groupCls;
- for (i = 0; i < missingColumnsCount; i++) {
- row.createChild({
- cls: cls,
- tag: 'td',
- vAlign: 'top'
- });
- }
- }
- },
- removeExceedingColumns : function(itemsCount) {
- var me = this,
- existingColumnsCount = me.columnNodes.length,
- exceedingColumnsCount,
- row,
- i;
- if (existingColumnsCount > itemsCount) {
- exceedingColumnsCount = existingColumnsCount - itemsCount;
- row = me.rowEl;
- for (i = 0; i < exceedingColumnsCount; i++) {
- row.last().remove();
- }
- }
- },
- <span id='Ext-layout-container-CheckboxGroup-method-renderItem'> /**
- </span> * Renders the given Component into the specified row and column
- * @param {Ext.Component} item The Component to render
- * @param {number} rowIndex row index
- * @param {number} columnIndex column index
- * @private
- */
- renderItem : function(item, rowIndex, columnIndex) {
- var me = this;
- me.configureItem(item);
- item.render(Ext.get(me.columnNodes[columnIndex]), rowIndex);
- me.afterRenderItem(item);
- },
- <span id='Ext-layout-container-CheckboxGroup-method-moveItem'> /**
- </span> * Moves the given already rendered Component to the specified row and column
- * @param {Ext.Component} item The Component to move
- * @param {number} rowIndex row index
- * @param {number} columnIndex column index
- * @private
- */
- moveItem : function(item, rowIndex, columnIndex) {
- var me = this,
- column = me.columnNodes[columnIndex],
- targetNode = column.childNodes[rowIndex];
- column.insertBefore(item.el.dom, targetNode || null);
- }
- });</pre>
- </body>
- </html>
|