Upgrade to ExtJS 4.0.0 - Released 04/26/2011
[extjs.git] / src / layout / container / CheckboxGroup.js
1 /**
2  * @class Ext.layout.container.CheckboxGroup
3  * @extends Ext.layout.container.Container
4  * <p>This layout implements the column arrangement for {@link Ext.form.CheckboxGroup} and {@link Ext.form.RadioGroup}.
5  * It groups the component's sub-items into columns based on the component's
6  * {@link Ext.form.CheckboxGroup#columns columns} and {@link Ext.form.CheckboxGroup#vertical} config properties.</p>
7  *
8  */
9 Ext.define('Ext.layout.container.CheckboxGroup', {
10     extend: 'Ext.layout.container.Container',
11     alias: ['layout.checkboxgroup'],
12
13
14     onLayout: function() {
15         var numCols = this.getColCount(),
16             shadowCt = this.getShadowCt(),
17             owner = this.owner,
18             items = owner.items,
19             shadowItems = shadowCt.items,
20             numItems = items.length,
21             colIndex = 0,
22             i, numRows;
23
24         // Distribute the items into the appropriate column containers. We add directly to the
25         // containers' items collection rather than calling container.add(), because we need the
26         // checkboxes to maintain their original ownerCt. The distribution is done on each layout
27         // in case items have been added, removed, or reordered.
28
29         shadowItems.each(function(col) {
30             col.items.clear();
31         });
32
33         // If columns="auto", then the number of required columns may change as checkboxes are added/removed
34         // from the CheckboxGroup; adjust to match.
35         while (shadowItems.length > numCols) {
36             shadowCt.remove(shadowItems.last());
37         }
38         while (shadowItems.length < numCols) {
39             shadowCt.add({
40                 xtype: 'container',
41                 cls: owner.groupCls,
42                 flex: 1
43             });
44         }
45
46         if (owner.vertical) {
47             numRows = Math.ceil(numItems / numCols);
48             for (i = 0; i < numItems; i++) {
49                 if (i > 0 && i % numRows === 0) {
50                     colIndex++;
51                 }
52                 shadowItems.getAt(colIndex).items.add(items.getAt(i));
53             }
54         } else {
55             for (i = 0; i < numItems; i++) {
56                 colIndex = i % numCols;
57                 shadowItems.getAt(colIndex).items.add(items.getAt(i));
58             }
59         }
60
61         if (!shadowCt.rendered) {
62             shadowCt.render(this.getRenderTarget());
63         } else {
64             // Ensure all items are rendered in the correct place in the correct column - this won't
65             // get done by the column containers themselves if their dimensions are not changing.
66             shadowItems.each(function(col) {
67                 var layout = col.getLayout();
68                 layout.renderItems(layout.getLayoutItems(), layout.getRenderTarget());
69             });
70         }
71
72         shadowCt.doComponentLayout();
73     },
74
75
76     // We don't want to render any items to the owner directly, that gets handled by each column's own layout
77     renderItems: Ext.emptyFn,
78
79
80     /**
81      * @private
82      * Creates and returns the shadow hbox container that will be used to arrange the owner's items
83      * into columns.
84      */
85     getShadowCt: function() {
86         var me = this,
87             shadowCt = me.shadowCt,
88             owner, items, item, columns, columnsIsArray, numCols, i;
89
90         if (!shadowCt) {
91             // Create the column containers based on the owner's 'columns' config
92             owner = me.owner;
93             columns = owner.columns;
94             columnsIsArray = Ext.isArray(columns);
95             numCols = me.getColCount();
96             items = [];
97             for(i = 0; i < numCols; i++) {
98                 item = {
99                     xtype: 'container',
100                     cls: owner.groupCls
101                 };
102                 if (columnsIsArray) {
103                     // Array can contain mixture of whole numbers, used as fixed pixel widths, and fractional
104                     // numbers, used as relative flex values.
105                     if (columns[i] < 1) {
106                         item.flex = columns[i];
107                     } else {
108                         item.width = columns[i];
109                     }
110                 }
111                 else {
112                     // All columns the same width
113                     item.flex = 1;
114                 }
115                 items.push(item);
116             }
117
118             // Create the shadow container; delay rendering until after items are added to the columns
119             shadowCt = me.shadowCt = Ext.createWidget('container', {
120                 layout: 'hbox',
121                 items: items,
122                 ownerCt: owner
123             });
124         }
125         
126         return shadowCt;
127     },
128
129
130     /**
131      * @private Get the number of columns in the checkbox group
132      */
133     getColCount: function() {
134         var owner = this.owner,
135             colsCfg = owner.columns;
136         return Ext.isArray(colsCfg) ? colsCfg.length : (Ext.isNumber(colsCfg) ? colsCfg : owner.items.length);
137     }
138
139 });