3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.form.field.Checkbox
17 * @extends Ext.form.field.Base
19 Single checkbox field. Can be used as a direct replacement for traditional checkbox fields. Also serves as a
20 parent class for {@link Ext.form.field.Radio radio buttons}.
22 __Labeling:__ In addition to the {@link Ext.form.Labelable standard field labeling options}, checkboxes
23 may be given an optional {@link #boxLabel} which will be displayed immediately after checkbox. Also see
24 {@link Ext.form.CheckboxGroup} for a convenient method of grouping related checkboxes.
27 The main value of a checkbox is a boolean, indicating whether or not the checkbox is checked.
28 The following values will check the checkbox:
34 Any other value will uncheck the checkbox.
36 In addition to the main boolean value, you may also specify a separate {@link #inputValue}. This will be
37 sent as the parameter value when the form is {@link Ext.form.Basic#submit submitted}. You will want to set
38 this value if you have multiple checkboxes with the same {@link #name}. If not specified, the value `on`
40 {@img Ext.form.Checkbox/Ext.form.Checkbox.png Ext.form.Checkbox Checkbox component}
43 Ext.create('Ext.form.Panel', {
46 title : 'Pizza Order',
49 xtype : 'fieldcontainer',
50 fieldLabel : 'Toppings',
51 defaultType: 'checkboxfield',
54 boxLabel : 'Anchovies',
59 boxLabel : 'Artichoke Hearts',
77 var checkbox = Ext.getCmp('checkbox3');
78 checkbox.setValue(true);
85 var checkbox1 = Ext.getCmp('checkbox1'),
86 checkbox2 = Ext.getCmp('checkbox2'),
87 checkbox3 = Ext.getCmp('checkbox3');
89 checkbox1.setValue(true);
90 checkbox2.setValue(true);
91 checkbox3.setValue(true);
97 var checkbox1 = Ext.getCmp('checkbox1'),
98 checkbox2 = Ext.getCmp('checkbox2'),
99 checkbox3 = Ext.getCmp('checkbox3');
101 checkbox1.setValue(false);
102 checkbox2.setValue(false);
103 checkbox3.setValue(false);
107 renderTo: Ext.getBody()
110 * @docauthor Robert Dougan <rob@sencha.com>
113 Ext.define('Ext.form.field.Checkbox', {
114 extend: 'Ext.form.field.Base',
115 alias: ['widget.checkboxfield', 'widget.checkbox'],
116 alternateClassName: 'Ext.form.Checkbox',
117 requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'],
120 '<tpl if="boxLabel && boxLabelAlign == \'before\'">',
121 '<label class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
123 // Creates not an actual checkbox, but a button which is given aria role="checkbox" and
124 // styled with a custom checkbox image. This allows greater control and consistency in
125 // styling, and using a button allows it to gain focus and handle keyboard nav properly.
126 '<input type="button" id="{id}" ',
127 '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
128 'class="{fieldCls} {typeCls}" autocomplete="off" hidefocus="true" />',
129 '<tpl if="boxLabel && boxLabelAlign == \'after\'">',
130 '<label class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
133 disableFormats: true,
141 * @cfg {String} focusCls The CSS class to use when the checkbox receives focus
142 * (defaults to <tt>'x-form-cb-focus'</tt>)
144 focusCls: Ext.baseCSSPrefix + 'form-cb-focus',
147 * @cfg {String} fieldCls The default CSS class for the checkbox (defaults to <tt>'x-form-field'</tt>)
151 * @cfg {String} fieldBodyCls
152 * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}.
153 * Defaults to 'x-form-cb-wrap.
155 fieldBodyCls: Ext.baseCSSPrefix + 'form-cb-wrap',
158 * @cfg {Boolean} checked <tt>true</tt> if the checkbox should render initially checked (defaults to <tt>false</tt>)
163 * @cfg {String} checkedCls The CSS class added to the component's main element when it is in the checked state.
165 checkedCls: Ext.baseCSSPrefix + 'form-cb-checked',
168 * @cfg {String} boxLabel An optional text label that will appear next to the checkbox. Whether it appears before
169 * or after the checkbox is determined by the {@link #boxLabelAlign} config (defaults to after).
173 * @cfg {String} boxLabelCls The CSS class to be applied to the {@link #boxLabel} element
175 boxLabelCls: Ext.baseCSSPrefix + 'form-cb-label',
178 * @cfg {String} boxLabelAlign The position relative to the checkbox where the {@link #boxLabel} should
179 * appear. Recognized values are <tt>'before'</tt> and <tt>'after'</tt>. Defaults to <tt>'after'</tt>.
181 boxLabelAlign: 'after',
184 * @cfg {String} inputValue The value that should go into the generated input element's value attribute and
185 * should be used as the parameter value when submitting as part of a form. Defaults to <tt>"on"</tt>.
190 * @cfg {String} uncheckedValue If configured, this will be submitted as the checkbox's value during form
191 * submit if the checkbox is unchecked. By default this is undefined, which results in nothing being
192 * submitted for the checkbox field when the form is submitted (the default behavior of HTML checkboxes).
196 * @cfg {Function} handler A function called when the {@link #checked} value changes (can be used instead of
197 * handling the {@link #change change event}). The handler is passed the following parameters:
198 * <div class="mdetail-params"><ul>
199 * <li><b>checkbox</b> : Ext.form.field.Checkbox<div class="sub-desc">The Checkbox being toggled.</div></li>
200 * <li><b>checked</b> : Boolean<div class="sub-desc">The new checked state of the checkbox.</div></li>
205 * @cfg {Object} scope An object to use as the scope ('this' reference) of the {@link #handler} function
206 * (defaults to this Checkbox).
210 checkChangeEvents: [],
211 inputType: 'checkbox',
212 ariaRole: 'checkbox',
217 initComponent: function(){
218 this.callParent(arguments);
219 this.getManager().add(this);
222 initValue: function() {
224 checked = !!me.checked;
227 * The original value of the field as configured in the {@link #checked} configuration, or
228 * as loaded by the last form load operation if the form's {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad}
229 * setting is <code>true</code>.
231 * @property originalValue
233 me.originalValue = me.lastValue = checked;
235 // Set the initial checked state
236 me.setValue(checked);
240 onRender : function(ct, position) {
242 Ext.applyIf(me.renderSelectors, {
244 * @property boxLabelEl
245 * @type Ext.core.Element
246 * A reference to the label element created for the {@link #boxLabel}. Only present if the
247 * component has been rendered and has a boxLabel configured.
249 boxLabelEl: 'label.' + me.boxLabelCls
251 Ext.applyIf(me.subTplData, {
252 boxLabel: me.boxLabel,
253 boxLabelCls: me.boxLabelCls,
254 boxLabelAlign: me.boxLabelAlign
257 me.callParent(arguments);
260 initEvents: function() {
263 me.mon(me.inputEl, 'click', me.onBoxClick, me);
267 * @private Handle click on the checkbox button
269 onBoxClick: function(e) {
271 if (!me.disabled && !me.readOnly) {
272 this.setValue(!this.checked);
277 * Returns the checked state of the checkbox.
278 * @return {Boolean} True if checked, else false
280 getRawValue: function() {
285 * Returns the checked state of the checkbox.
286 * @return {Boolean} True if checked, else false
288 getValue: function() {
293 * Returns the submit value for the checkbox which can be used when submitting forms.
294 * @return {Boolean/null} True if checked; otherwise either the {@link #uncheckedValue} or null.
296 getSubmitValue: function() {
297 var unchecked = this.uncheckedValue,
298 uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null;
299 return this.checked ? this.inputValue : uncheckedVal;
303 * Sets the checked state of the checkbox.
304 * @param {Boolean/String} value The following values will check the checkbox:
305 * <code>true, 'true', '1', or 'on'</code>, as well as a String that matches the {@link #inputValue}.
306 * Any other value will uncheck the checkbox.
307 * @return {Boolean} the new checked state of the checkbox
309 setRawValue: function(value) {
311 inputEl = me.inputEl,
312 inputValue = me.inputValue,
313 checked = (value === true || value === 'true' || value === '1' ||
314 ((Ext.isString(value) && inputValue) ? value == inputValue : me.onRe.test(value)));
317 inputEl.dom.setAttribute('aria-checked', checked);
318 me[checked ? 'addCls' : 'removeCls'](me.checkedCls);
321 me.checked = me.rawValue = checked;
326 * Sets the checked state of the checkbox, and invokes change detection.
327 * @param {Boolean/String} checked The following values will check the checkbox:
328 * <code>true, 'true', '1', or 'on'</code>, as well as a String that matches the {@link #inputValue}.
329 * Any other value will uncheck the checkbox.
330 * @return {Ext.form.field.Checkbox} this
332 setValue: function(checked) {
335 // If an array of strings is passed, find all checkboxes in the group with the same name as this
336 // one and check all those whose inputValue is in the array, unchecking all the others. This is to
337 // facilitate setting values from Ext.form.Basic#setValues, but is not publicly documented as we
338 // don't want users depending on this behavior.
339 if (Ext.isArray(checked)) {
340 me.getManager().getByName(me.name).each(function(cb) {
341 cb.setValue(Ext.Array.contains(checked, cb.inputValue));
344 me.callParent(arguments);
351 valueToRaw: function(value) {
352 // No extra conversion for checkboxes
358 * Called when the checkbox's checked state changes. Invokes the {@link #handler} callback
359 * function if specified.
361 onChange: function(newVal, oldVal) {
363 handler = me.handler;
365 handler.call(me.scope || me, me, newVal);
367 me.callParent(arguments);
371 getManager: function() {
372 return Ext.form.CheckboxManager;
375 onEnable: function() {
377 inputEl = me.inputEl;
380 // Can still be disabled if the field is readOnly
381 inputEl.dom.disabled = me.readOnly;
385 setReadOnly: function(readOnly) {
387 inputEl = me.inputEl;
389 // Set the button to disabled when readonly
390 inputEl.dom.disabled = readOnly || me.disabled;
392 me.readOnly = readOnly;
396 * @protected Calculate and return the natural width of the bodyEl. It's possible that the initial
397 * rendering will cause the boxLabel to wrap and give us a bad width, so we must prevent wrapping
400 getBodyNaturalWidth: function() {
405 bodyEl.setStyle(ws, 'nowrap');
406 width = bodyEl.getWidth();
407 bodyEl.setStyle(ws, '');