Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / CheckboxGroup.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-form-CheckboxGroup'>/**
19 </span> * A {@link Ext.form.FieldContainer field container} which has a specialized layout for arranging
20  * {@link Ext.form.field.Checkbox} controls into columns, and provides convenience
21  * {@link Ext.form.field.Field} methods for {@link #getValue getting}, {@link #setValue setting},
22  * and {@link #validate validating} the group of checkboxes as a whole.
23  *
24  * # Validation
25  *
26  * Individual checkbox fields themselves have no default validation behavior, but
27  * sometimes you want to require a user to select at least one of a group of checkboxes. CheckboxGroup
28  * allows this by setting the config `{@link #allowBlank}:false`; when the user does not check at
29  * least one of the checkboxes, the entire group will be highlighted as invalid and the
30  * {@link #blankText error message} will be displayed according to the {@link #msgTarget} config.
31  *
32  * # Layout
33  *
34  * The default layout for CheckboxGroup makes it easy to arrange the checkboxes into
35  * columns; see the {@link #columns} and {@link #vertical} config documentation for details. You may also
36  * use a completely different layout by setting the {@link #layout} to one of the other supported layout
37  * types; for instance you may wish to use a custom arrangement of hbox and vbox containers. In that case
38  * the checkbox components at any depth will still be managed by the CheckboxGroup's validation.
39  *
40  *     @example
41  *     Ext.create('Ext.form.Panel', {
42  *         title: 'Checkbox Group',
43  *         width: 300,
44  *         height: 125,
45  *         bodyPadding: 10,
46  *         renderTo: Ext.getBody(),
47  *         items:[{
48  *             xtype: 'checkboxgroup',
49  *             fieldLabel: 'Two Columns',
50  *             // Arrange radio buttons into two columns, distributed vertically
51  *             columns: 2,
52  *             vertical: true,
53  *             items: [
54  *                 { boxLabel: 'Item 1', name: 'rb', inputValue: '1' },
55  *                 { boxLabel: 'Item 2', name: 'rb', inputValue: '2', checked: true },
56  *                 { boxLabel: 'Item 3', name: 'rb', inputValue: '3' },
57  *                 { boxLabel: 'Item 4', name: 'rb', inputValue: '4' },
58  *                 { boxLabel: 'Item 5', name: 'rb', inputValue: '5' },
59  *                 { boxLabel: 'Item 6', name: 'rb', inputValue: '6' }
60  *             ]
61  *         }]
62  *     });
63  */
64 Ext.define('Ext.form.CheckboxGroup', {
65     extend:'Ext.form.FieldContainer',
66     mixins: {
67         field: 'Ext.form.field.Field'
68     },
69     alias: 'widget.checkboxgroup',
70     requires: ['Ext.layout.container.CheckboxGroup', 'Ext.form.field.Base'],
71
72 <span id='Ext-form-CheckboxGroup-cfg-name'>    /**
73 </span>     * @cfg {String} name
74      * @hide
75      */
76
77 <span id='Ext-form-CheckboxGroup-cfg-items'>    /**
78 </span>     * @cfg {Ext.form.field.Checkbox[]/Object[]} items
79      * An Array of {@link Ext.form.field.Checkbox Checkbox}es or Checkbox config objects to arrange in the group.
80      */
81
82 <span id='Ext-form-CheckboxGroup-cfg-columns'>    /**
83 </span>     * @cfg {String/Number/Number[]} columns
84      * Specifies the number of columns to use when displaying grouped checkbox/radio controls using automatic layout.
85      * This config can take several types of values:
86      *
87      * - 'auto' - The controls will be rendered one per column on one row and the width of each column will be evenly
88      *   distributed based on the width of the overall field container. This is the default.
89      * - Number - If you specific a number (e.g., 3) that number of columns will be created and the contained controls
90      *   will be automatically distributed based on the value of {@link #vertical}.
91      * - Array - You can also specify an array of column widths, mixing integer (fixed width) and float (percentage
92      *   width) values as needed (e.g., [100, .25, .75]). Any integer values will be rendered first, then any float
93      *   values will be calculated as a percentage of the remaining space. Float values do not have to add up to 1
94      *   (100%) although if you want the controls to take up the entire field container you should do so.
95      */
96     columns : 'auto',
97
98 <span id='Ext-form-CheckboxGroup-cfg-vertical'>    /**
99 </span>     * @cfg {Boolean} vertical
100      * True to distribute contained controls across columns, completely filling each column top to bottom before
101      * starting on the next column. The number of controls in each column will be automatically calculated to keep
102      * columns as even as possible. The default value is false, so that controls will be added to columns one at a time,
103      * completely filling each row left to right before starting on the next row.
104      */
105     vertical : false,
106
107 <span id='Ext-form-CheckboxGroup-cfg-allowBlank'>    /**
108 </span>     * @cfg {Boolean} allowBlank
109      * False to validate that at least one item in the group is checked. If no items are selected at
110      * validation time, {@link #blankText} will be used as the error text.
111      */
112     allowBlank : true,
113
114 <span id='Ext-form-CheckboxGroup-cfg-blankText'>    /**
115 </span>     * @cfg {String} blankText
116      * Error text to display if the {@link #allowBlank} validation fails
117      */
118     blankText : &quot;You must select at least one item in this group&quot;,
119
120     // private
121     defaultType : 'checkboxfield',
122
123     // private
124     groupCls : Ext.baseCSSPrefix + 'form-check-group',
125
126 <span id='Ext-form-CheckboxGroup-cfg-fieldBodyCls'>    /**
127 </span>     * @cfg {String} fieldBodyCls
128      * An extra CSS class to be applied to the body content element in addition to {@link #baseBodyCls}.
129      * Defaults to 'x-form-checkboxgroup-body'.
130      */
131     fieldBodyCls: Ext.baseCSSPrefix + 'form-checkboxgroup-body',
132
133     // private
134     layout: 'checkboxgroup',
135
136     initComponent: function() {
137         var me = this;
138         me.callParent();
139         me.initField();
140     },
141
142 <span id='Ext-form-CheckboxGroup-method-initValue'>    /**
143 </span>     * Initializes the field's value based on the initial config. If the {@link #value} config is specified then we use
144      * that to set the value; otherwise we initialize the originalValue by querying the values of all sub-checkboxes
145      * after they have been initialized.
146      * @protected
147      */
148     initValue: function() {
149         var me = this,
150             valueCfg = me.value;
151         me.originalValue = me.lastValue = valueCfg || me.getValue();
152         if (valueCfg) {
153             me.setValue(valueCfg);
154         }
155     },
156
157 <span id='Ext-form-CheckboxGroup-method-onFieldAdded'>    /**
158 </span>     * When a checkbox is added to the group, monitor it for changes
159      * @param {Object} field
160      * @protected
161      */
162     onFieldAdded: function(field) {
163         var me = this;
164         if (field.isCheckbox) {
165             me.mon(field, 'change', me.checkChange, me);
166         }
167         me.callParent(arguments);
168     },
169
170     onFieldRemoved: function(field) {
171         var me = this;
172         if (field.isCheckbox) {
173             me.mun(field, 'change', me.checkChange, me);
174         }
175         me.callParent(arguments);
176     },
177
178     // private override - the group value is a complex object, compare using object serialization
179     isEqual: function(value1, value2) {
180         var toQueryString = Ext.Object.toQueryString;
181         return toQueryString(value1) === toQueryString(value2);
182     },
183
184 <span id='Ext-form-CheckboxGroup-method-getErrors'>    /**
185 </span>     * Runs CheckboxGroup's validations and returns an array of any errors. The only error by default is if allowBlank
186      * is set to true and no items are checked.
187      * @return {String[]} Array of all validation errors
188      */
189     getErrors: function() {
190         var errors = [];
191         if (!this.allowBlank &amp;&amp; Ext.isEmpty(this.getChecked())) {
192             errors.push(this.blankText);
193         }
194         return errors;
195     },
196
197 <span id='Ext-form-CheckboxGroup-method-getBoxes'>    /**
198 </span>     * @private Returns all checkbox components within the container
199      */
200     getBoxes: function() {
201         return this.query('[isCheckbox]');
202     },
203
204 <span id='Ext-form-CheckboxGroup-method-eachBox'>    /**
205 </span>     * @private Convenience function which calls the given function for every checkbox in the group
206      * @param {Function} fn The function to call
207      * @param {Object} scope (Optional) scope object
208      */
209     eachBox: function(fn, scope) {
210         Ext.Array.forEach(this.getBoxes(), fn, scope || this);
211     },
212
213 <span id='Ext-form-CheckboxGroup-method-getChecked'>    /**
214 </span>     * Returns an Array of all checkboxes in the container which are currently checked
215      * @return {Ext.form.field.Checkbox[]} Array of Ext.form.field.Checkbox components
216      */
217     getChecked: function() {
218         return Ext.Array.filter(this.getBoxes(), function(cb) {
219             return cb.getValue();
220         });
221     },
222
223     // private override
224     isDirty: function(){
225         return Ext.Array.some(this.getBoxes(), function(cb) {
226             return cb.isDirty();
227         });
228     },
229
230     // private override
231     setReadOnly: function(readOnly) {
232         this.eachBox(function(cb) {
233             cb.setReadOnly(readOnly);
234         });
235         this.readOnly = readOnly;
236     },
237
238 <span id='Ext-form-CheckboxGroup-method-reset'>    /**
239 </span>     * Resets the checked state of all {@link Ext.form.field.Checkbox checkboxes} in the group to their originally
240      * loaded values and clears any validation messages.
241      * See {@link Ext.form.Basic}.{@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad}
242      */
243     reset: function() {
244         var me = this,
245             hadError = me.hasActiveError(),
246             preventMark = me.preventMark;
247         me.preventMark = true;
248         me.batchChanges(function() {
249             me.eachBox(function(cb) {
250                 cb.reset();
251             });
252         });
253         me.preventMark = preventMark;
254         me.unsetActiveError();
255         if (hadError) {
256             me.doComponentLayout();
257         }
258     },
259
260     // private override
261     resetOriginalValue: function() {
262         // Defer resetting of originalValue until after all sub-checkboxes have been reset so we get
263         // the correct data from getValue()
264         Ext.defer(function() {
265             this.callParent();
266         }, 1, this);
267     },
268
269
270 <span id='Ext-form-CheckboxGroup-method-setValue'>    /**
271 </span>     * Sets the value(s) of all checkboxes in the group. The expected format is an Object of name-value pairs
272      * corresponding to the names of the checkboxes in the group. Each pair can have either a single or multiple values:
273      *
274      *   - A single Boolean or String value will be passed to the `setValue` method of the checkbox with that name.
275      *     See the rules in {@link Ext.form.field.Checkbox#setValue} for accepted values.
276      *   - An Array of String values will be matched against the {@link Ext.form.field.Checkbox#inputValue inputValue}
277      *     of checkboxes in the group with that name; those checkboxes whose inputValue exists in the array will be
278      *     checked and others will be unchecked.
279      *
280      * If a checkbox's name is not in the mapping at all, it will be unchecked.
281      *
282      * An example:
283      *
284      *     var myCheckboxGroup = new Ext.form.CheckboxGroup({
285      *         columns: 3,
286      *         items: [{
287      *             name: 'cb1',
288      *             boxLabel: 'Single 1'
289      *         }, {
290      *             name: 'cb2',
291      *             boxLabel: 'Single 2'
292      *         }, {
293      *             name: 'cb3',
294      *             boxLabel: 'Single 3'
295      *         }, {
296      *             name: 'cbGroup',
297      *             boxLabel: 'Grouped 1'
298      *             inputValue: 'value1'
299      *         }, {
300      *             name: 'cbGroup',
301      *             boxLabel: 'Grouped 2'
302      *             inputValue: 'value2'
303      *         }, {
304      *             name: 'cbGroup',
305      *             boxLabel: 'Grouped 3'
306      *             inputValue: 'value3'
307      *         }]
308      *     });
309      *
310      *     myCheckboxGroup.setValue({
311      *         cb1: true,
312      *         cb3: false,
313      *         cbGroup: ['value1', 'value3']
314      *     });
315      *
316      * The above code will cause the checkbox named 'cb1' to be checked, as well as the first and third checkboxes named
317      * 'cbGroup'. The other three checkboxes will be unchecked.
318      *
319      * @param {Object} value The mapping of checkbox names to values.
320      * @return {Ext.form.CheckboxGroup} this
321      */
322     setValue: function(value) {
323         var me = this;
324         me.batchChanges(function() {
325             me.eachBox(function(cb) {
326                 var name = cb.getName(),
327                     cbValue = false;
328                 if (value &amp;&amp; name in value) {
329                     if (Ext.isArray(value[name])) {
330                         cbValue = Ext.Array.contains(value[name], cb.inputValue);
331                     } else {
332                         // single value, let the checkbox's own setValue handle conversion
333                         cbValue = value[name];
334                     }
335                 }
336                 cb.setValue(cbValue);
337             });
338         });
339         return me;
340     },
341
342
343 <span id='Ext-form-CheckboxGroup-method-getValue'>    /**
344 </span>     * Returns an object containing the values of all checked checkboxes within the group. Each key-value pair in the
345      * object corresponds to a checkbox {@link Ext.form.field.Checkbox#name name}. If there is only one checked checkbox
346      * with a particular name, the value of that pair will be the String {@link Ext.form.field.Checkbox#inputValue
347      * inputValue} of that checkbox. If there are multiple checked checkboxes with that name, the value of that pair
348      * will be an Array of the selected inputValues.
349      *
350      * The object format returned from this method can also be passed directly to the {@link #setValue} method.
351      *
352      * NOTE: In Ext 3, this method returned an array of Checkbox components; this was changed to make it more consistent
353      * with other field components and with the {@link #setValue} argument signature. If you need the old behavior in
354      * Ext 4+, use the {@link #getChecked} method instead.
355      */
356     getValue: function() {
357         var values = {};
358         this.eachBox(function(cb) {
359             var name = cb.getName(),
360                 inputValue = cb.inputValue,
361                 bucket;
362             if (cb.getValue()) {
363                 if (name in values) {
364                     bucket = values[name];
365                     if (!Ext.isArray(bucket)) {
366                         bucket = values[name] = [bucket];
367                     }
368                     bucket.push(inputValue);
369                 } else {
370                     values[name] = inputValue;
371                 }
372             }
373         });
374         return values;
375     },
376
377     /*
378      * Don't return any data for submit; the form will get the info from the individual checkboxes themselves.
379      */
380     getSubmitData: function() {
381         return null;
382     },
383
384     /*
385      * Don't return any data for the model; the form will get the info from the individual checkboxes themselves.
386      */
387     getModelData: function() {
388         return null;
389     },
390
391     validate: function() {
392         var me = this,
393             errors = me.getErrors(),
394             isValid = Ext.isEmpty(errors),
395             wasValid = !me.hasActiveError();
396
397         if (isValid) {
398             me.unsetActiveError();
399         } else {
400             me.setActiveError(errors);
401         }
402         if (isValid !== wasValid) {
403             me.fireEvent('validitychange', me, isValid);
404             me.doComponentLayout();
405         }
406
407         return isValid;
408     }
409
410 }, function() {
411
412     this.borrow(Ext.form.field.Base, ['markInvalid', 'clearInvalid']);
413
414 });
415
416 </pre>
417 </body>
418 </html>