Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / docs / source / CheckboxGroup.html
1 <html>
2 <head>
3   <title>The source code</title>
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
6 </head>
7 <body  onload="prettyPrint();">
8     <pre class="prettyprint lang-js">/*!
9  * Ext JS Library 3.0.3
10  * Copyright(c) 2006-2009 Ext JS, LLC
11  * licensing@extjs.com
12  * http://www.extjs.com/license
13  */
14 <div id="cls-Ext.form.CheckboxGroup"></div>/**\r
15  * @class Ext.form.CheckboxGroup\r
16  * @extends Ext.form.Field\r
17  * <p>A grouping container for {@link Ext.form.Checkbox} controls.</p>\r
18  * <p>Sample usage:</p>\r
19  * <pre><code>\r
20 var myCheckboxGroup = new Ext.form.CheckboxGroup({\r
21     id:'myGroup',\r
22     xtype: 'checkboxgroup',\r
23     fieldLabel: 'Single Column',\r
24     itemCls: 'x-check-group-alt',\r
25     // Put all controls in a single column with width 100%\r
26     columns: 1,\r
27     items: [\r
28         {boxLabel: 'Item 1', name: 'cb-col-1'},\r
29         {boxLabel: 'Item 2', name: 'cb-col-2', checked: true},\r
30         {boxLabel: 'Item 3', name: 'cb-col-3'}\r
31     ]\r
32 });\r
33  * </code></pre>\r
34  * @constructor\r
35  * Creates a new CheckboxGroup\r
36  * @param {Object} config Configuration options\r
37  * @xtype checkboxgroup\r
38  */\r
39 Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {\r
40     <div id="cfg-Ext.form.CheckboxGroup-items"></div>/**\r
41      * @cfg {Array} items An Array of {@link Ext.form.Checkbox Checkbox}es or Checkbox config objects\r
42      * to arrange in the group.\r
43      */\r
44     <div id="cfg-Ext.form.CheckboxGroup-columns"></div>/**\r
45      * @cfg {String/Number/Array} columns Specifies the number of columns to use when displaying grouped\r
46      * checkbox/radio controls using automatic layout.  This config can take several types of values:\r
47      * <ul><li><b>'auto'</b> : <p class="sub-desc">The controls will be rendered one per column on one row and the width\r
48      * of each column will be evenly distributed based on the width of the overall field container. This is the default.</p></li>\r
49      * <li><b>Number</b> : <p class="sub-desc">If you specific a number (e.g., 3) that number of columns will be \r
50      * created and the contained controls will be automatically distributed based on the value of {@link #vertical}.</p></li>\r
51      * <li><b>Array</b> : Object<p class="sub-desc">You can also specify an array of column widths, mixing integer\r
52      * (fixed width) and float (percentage width) values as needed (e.g., [100, .25, .75]). Any integer values will\r
53      * be rendered first, then any float values will be calculated as a percentage of the remaining space. Float\r
54      * values do not have to add up to 1 (100%) although if you want the controls to take up the entire field\r
55      * container you should do so.</p></li></ul>\r
56      */\r
57     columns : 'auto',\r
58     <div id="cfg-Ext.form.CheckboxGroup-vertical"></div>/**\r
59      * @cfg {Boolean} vertical True to distribute contained controls across columns, completely filling each column \r
60      * top to bottom before starting on the next column.  The number of controls in each column will be automatically\r
61      * calculated to keep columns as even as possible.  The default value is false, so that controls will be added\r
62      * to columns one at a time, completely filling each row left to right before starting on the next row.\r
63      */\r
64     vertical : false,\r
65     <div id="cfg-Ext.form.CheckboxGroup-allowBlank"></div>/**\r
66      * @cfg {Boolean} allowBlank False to validate that at least one item in the group is checked (defaults to true).\r
67      * If no items are selected at validation time, {@link @blankText} will be used as the error text.\r
68      */\r
69     allowBlank : true,\r
70     <div id="cfg-Ext.form.CheckboxGroup-blankText"></div>/**\r
71      * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails (defaults to "You must \r
72      * select at least one item in this group")\r
73      */\r
74     blankText : "You must select at least one item in this group",\r
75     \r
76     // private\r
77     defaultType : 'checkbox',\r
78     \r
79     // private\r
80     groupCls : 'x-form-check-group',\r
81     \r
82     // private\r
83     initComponent: function(){\r
84         this.addEvents(\r
85             <div id="event-Ext.form.CheckboxGroup-change"></div>/**\r
86              * @event change\r
87              * Fires when the state of a child checkbox changes.\r
88              * @param {Ext.form.CheckboxGroup} this\r
89              * @param {Array} checked An array containing the checked boxes.\r
90              */\r
91             'change'\r
92         );   \r
93         Ext.form.CheckboxGroup.superclass.initComponent.call(this);\r
94     },\r
95     \r
96     // private\r
97     onRender : function(ct, position){\r
98         if(!this.el){\r
99             var panelCfg = {\r
100                 id: this.id,\r
101                 cls: this.groupCls,\r
102                 layout: 'column',\r
103                 border: false,\r
104                 renderTo: ct,\r
105                 bufferResize: false // Default this to false, since it doesn't really have a proper ownerCt.\r
106             };\r
107             var colCfg = {\r
108                 defaultType: this.defaultType,\r
109                 layout: 'form',\r
110                 border: false,\r
111                 defaults: {\r
112                     hideLabel: true,\r
113                     anchor: '100%'\r
114                 }\r
115             };\r
116             \r
117             if(this.items[0].items){\r
118                 \r
119                 // The container has standard ColumnLayout configs, so pass them in directly\r
120                 \r
121                 Ext.apply(panelCfg, {\r
122                     layoutConfig: {columns: this.items.length},\r
123                     defaults: this.defaults,\r
124                     items: this.items\r
125                 });\r
126                 for(var i=0, len=this.items.length; i<len; i++){\r
127                     Ext.applyIf(this.items[i], colCfg);\r
128                 }\r
129                 \r
130             }else{\r
131                 \r
132                 // The container has field item configs, so we have to generate the column\r
133                 // panels first then move the items into the columns as needed.\r
134                 \r
135                 var numCols, cols = [];\r
136                 \r
137                 if(typeof this.columns == 'string'){ // 'auto' so create a col per item\r
138                     this.columns = this.items.length;\r
139                 }\r
140                 if(!Ext.isArray(this.columns)){\r
141                     var cs = [];\r
142                     for(var i=0; i<this.columns; i++){\r
143                         cs.push((100/this.columns)*.01); // distribute by even %\r
144                     }\r
145                     this.columns = cs;\r
146                 }\r
147                 \r
148                 numCols = this.columns.length;\r
149                 \r
150                 // Generate the column configs with the correct width setting\r
151                 for(var i=0; i<numCols; i++){\r
152                     var cc = Ext.apply({items:[]}, colCfg);\r
153                     cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];\r
154                     if(this.defaults){\r
155                         cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)\r
156                     }\r
157                     cols.push(cc);\r
158                 };\r
159                 \r
160                 // Distribute the original items into the columns\r
161                 if(this.vertical){\r
162                     var rows = Math.ceil(this.items.length / numCols), ri = 0;\r
163                     for(var i=0, len=this.items.length; i<len; i++){\r
164                         if(i>0 && i%rows==0){\r
165                             ri++;\r
166                         }\r
167                         if(this.items[i].fieldLabel){\r
168                             this.items[i].hideLabel = false;\r
169                         }\r
170                         cols[ri].items.push(this.items[i]);\r
171                     };\r
172                 }else{\r
173                     for(var i=0, len=this.items.length; i<len; i++){\r
174                         var ci = i % numCols;\r
175                         if(this.items[i].fieldLabel){\r
176                             this.items[i].hideLabel = false;\r
177                         }\r
178                         cols[ci].items.push(this.items[i]);\r
179                     };\r
180                 }\r
181                 \r
182                 Ext.apply(panelCfg, {\r
183                     layoutConfig: {columns: numCols},\r
184                     items: cols\r
185                 });\r
186             }\r
187             \r
188             this.panel = new Ext.Panel(panelCfg);\r
189             this.panel.ownerCt = this;\r
190             this.el = this.panel.getEl();\r
191             \r
192             if(this.forId && this.itemCls){\r
193                 var l = this.el.up(this.itemCls).child('label', true);\r
194                 if(l){\r
195                     l.setAttribute('htmlFor', this.forId);\r
196                 }\r
197             }\r
198             \r
199             var fields = this.panel.findBy(function(c){\r
200                 return c.isFormField;\r
201             }, this);\r
202             \r
203             this.items = new Ext.util.MixedCollection();\r
204             this.items.addAll(fields);\r
205         }\r
206         Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);\r
207     },\r
208     \r
209     initValue : function(){\r
210         if(this.value){\r
211             this.setValue.apply(this, this.buffered ? this.value : [this.value]);\r
212             delete this.buffered;\r
213             delete this.value;\r
214         }\r
215     },\r
216     \r
217     afterRender : function(){\r
218         Ext.form.CheckboxGroup.superclass.afterRender.call(this);\r
219         this.eachItem(function(item){\r
220             item.on('check', this.fireChecked, this);\r
221             item.inGroup = true;\r
222         });\r
223     },\r
224     \r
225     // private\r
226     doLayout: function(){\r
227         //ugly method required to layout hidden items\r
228         if(this.rendered){\r
229             this.panel.forceLayout = this.ownerCt.forceLayout;\r
230             this.panel.doLayout();\r
231         }\r
232     },\r
233     \r
234     // private\r
235     fireChecked: function(){\r
236         var arr = [];\r
237         this.eachItem(function(item){\r
238             if(item.checked){\r
239                 arr.push(item);\r
240             }\r
241         });\r
242         this.fireEvent('change', this, arr);\r
243     },\r
244     \r
245     // private\r
246     validateValue : function(value){\r
247         if(!this.allowBlank){\r
248             var blank = true;\r
249             this.eachItem(function(f){\r
250                 if(f.checked){\r
251                     return (blank = false);\r
252                 }\r
253             });\r
254             if(blank){\r
255                 this.markInvalid(this.blankText);\r
256                 return false;\r
257             }\r
258         }\r
259         return true;\r
260     },\r
261     \r
262     // private\r
263     isDirty: function(){\r
264         //override the behaviour to check sub items.\r
265         if (this.disabled || !this.rendered) {\r
266             return false;\r
267         }\r
268 \r
269         var dirty = false;\r
270         this.eachItem(function(item){\r
271             if(item.isDirty()){\r
272                 dirty = true;\r
273                 return false;\r
274             }\r
275         });\r
276         return dirty;\r
277     },\r
278     \r
279     // private\r
280     onDisable : function(){\r
281         this.eachItem(function(item){\r
282             item.disable();\r
283         });\r
284     },\r
285 \r
286     // private\r
287     onEnable : function(){\r
288         this.eachItem(function(item){\r
289             item.enable();\r
290         });\r
291     },\r
292     \r
293     // private\r
294     doLayout: function(){\r
295         if(this.rendered){\r
296             this.panel.forceLayout = this.ownerCt.forceLayout;\r
297             this.panel.doLayout();\r
298         }\r
299     },\r
300     \r
301     // private\r
302     onResize : function(w, h){\r
303         this.panel.setSize(w, h);\r
304         this.panel.doLayout();\r
305     },\r
306     \r
307     // inherit docs from Field\r
308     reset : function(){\r
309         Ext.form.CheckboxGroup.superclass.reset.call(this);\r
310         this.eachItem(function(c){\r
311             if(c.reset){\r
312                 c.reset();\r
313             }\r
314         });\r
315     },\r
316     \r
317     <div id="method-Ext.form.CheckboxGroup-setValue"></div>/**\r
318      * {@link Ext.form.Checkbox#setValue Set the value(s)} of an item or items\r
319      * in the group. Examples illustrating how this method may be called:\r
320      * <pre><code>\r
321 // call with name and value\r
322 myCheckboxGroup.setValue('cb-col-1', true);\r
323 // call with an array of boolean values \r
324 myCheckboxGroup.setValue([true, false, false]);\r
325 // call with an object literal specifying item:value pairs\r
326 myCheckboxGroup.setValue({\r
327     'cb-col-2': false,\r
328     'cb-col-3': true\r
329 });\r
330 // use comma separated string to set items with name to true (checked)\r
331 myCheckboxGroup.setValue('cb-col-1,cb-col-3');\r
332      * </code></pre>\r
333      * See {@link Ext.form.Checkbox#setValue} for additional information.\r
334      * @param {Mixed} id The checkbox to check, or as described by example shown.\r
335      * @param {Boolean} value (optional) The value to set the item.\r
336      * @return {Ext.form.CheckboxGroup} this\r
337      */\r
338     setValue: function(){\r
339         if(this.rendered){\r
340             this.onSetValue.apply(this, arguments);\r
341         }else{\r
342             this.buffered = true;\r
343             this.value = arguments;\r
344         }\r
345         return this;\r
346     },\r
347     \r
348     onSetValue: function(id, value){\r
349         if(arguments.length == 1){\r
350             if(Ext.isArray(id)){\r
351                 // an array of boolean values\r
352                 Ext.each(id, function(val, idx){\r
353                     var item = this.items.itemAt(idx);\r
354                     if(item){\r
355                         item.setValue(val);\r
356                     }\r
357                 }, this);\r
358             }else if(Ext.isObject(id)){\r
359                 // set of name/value pairs\r
360                 for(var i in id){\r
361                     var f = this.getBox(i);\r
362                     if(f){\r
363                         f.setValue(id[i]);\r
364                     }\r
365                 }\r
366             }else{\r
367                 this.setValueForItem(id);\r
368             }\r
369         }else{\r
370             var f = this.getBox(id);\r
371             if(f){\r
372                 f.setValue(value);\r
373             }\r
374         }\r
375     },\r
376     \r
377     // private\r
378     onDestroy: function(){\r
379         Ext.destroy(this.panel);\r
380         Ext.form.CheckboxGroup.superclass.onDestroy.call(this);\r
381 \r
382     },\r
383     \r
384     setValueForItem : function(val){\r
385         val = String(val).split(',');\r
386         this.eachItem(function(item){\r
387             if(val.indexOf(item.inputValue)> -1){\r
388                 item.setValue(true);\r
389             }\r
390         });\r
391     },\r
392     \r
393     // private\r
394     getBox : function(id){\r
395         var box = null;\r
396         this.eachItem(function(f){\r
397             if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){\r
398                 box = f;\r
399                 return false;\r
400             }\r
401         });\r
402         return box;\r
403     },\r
404     \r
405     <div id="method-Ext.form.CheckboxGroup-getValue"></div>/**\r
406      * Gets an array of the selected {@link Ext.form.Checkbox} in the group.\r
407      * @return {Array} An array of the selected checkboxes.\r
408      */\r
409     getValue : function(){\r
410         var out = [];\r
411         this.eachItem(function(item){\r
412             if(item.checked){\r
413                 out.push(item);\r
414             }\r
415         });\r
416         return out;\r
417     },\r
418     \r
419     // private\r
420     eachItem: function(fn){\r
421         if(this.items && this.items.each){\r
422             this.items.each(fn, this);\r
423         }\r
424     },\r
425     \r
426     <div id="cfg-Ext.form.CheckboxGroup-name"></div>/**\r
427      * @cfg {String} name\r
428      * @hide\r
429      */\r
430 \r
431     <div id="method-Ext.form.CheckboxGroup-getRawValue"></div>/**\r
432      * @method getRawValue\r
433      * @hide\r
434      */\r
435     getRawValue : Ext.emptyFn,\r
436     \r
437     <div id="method-Ext.form.CheckboxGroup-setRawValue"></div>/**\r
438      * @method setRawValue\r
439      * @hide\r
440      */\r
441     setRawValue : Ext.emptyFn\r
442     \r
443 });\r
444 \r
445 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);\r
446 </pre>
447 </body>
448 </html>