Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / Checkbox.html
index fc4adcf..258a2a4 100644 (file)
-<html>\r
-<head>\r
-  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />    \r
-  <title>The source code</title>\r
-    <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />\r
-    <script type="text/javascript" src="../resources/prettify/prettify.js"></script>\r
-</head>\r
-<body  onload="prettyPrint();">\r
-    <pre class="prettyprint lang-js"><div id="cls-Ext.form.Checkbox"></div>/**
- * @class Ext.form.Checkbox
- * @extends Ext.form.Field
- * Single checkbox field.  Can be used as a direct replacement for traditional checkbox fields.
- * @constructor
- * Creates a new Checkbox
- * @param {Object} config Configuration options
- * @xtype checkbox
+<!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-form-field-Checkbox'>/**
+</span> * @docauthor Robert Dougan &lt;rob@sencha.com&gt;
+ *
+ * Single checkbox field. Can be used as a direct replacement for traditional checkbox fields. Also serves as a
+ * parent class for {@link Ext.form.field.Radio radio buttons}.
+ *
+ * # Labeling
+ *
+ * In addition to the {@link Ext.form.Labelable standard field labeling options}, checkboxes
+ * may be given an optional {@link #boxLabel} which will be displayed immediately after checkbox. Also see
+ * {@link Ext.form.CheckboxGroup} for a convenient method of grouping related checkboxes.
+ *
+ * # Values
+ *
+ * The main value of a checkbox is a boolean, indicating whether or not the checkbox is checked.
+ * The following values will check the checkbox:
+ *
+ * - `true`
+ * - `'true'`
+ * - `'1'`
+ * - `'on'`
+ *
+ * Any other value will uncheck the checkbox.
+ *
+ * In addition to the main boolean value, you may also specify a separate {@link #inputValue}. This will be
+ * sent as the parameter value when the form is {@link Ext.form.Basic#submit submitted}. You will want to set
+ * this value if you have multiple checkboxes with the same {@link #name}. If not specified, the value `on`
+ * will be used.
+ *
+ * # Example usage
+ *
+ *     @example
+ *     Ext.create('Ext.form.Panel', {
+ *         bodyPadding: 10,
+ *         width: 300,
+ *         title: 'Pizza Order',
+ *         items: [
+ *             {
+ *                 xtype: 'fieldcontainer',
+ *                 fieldLabel: 'Toppings',
+ *                 defaultType: 'checkboxfield',
+ *                 items: [
+ *                     {
+ *                         boxLabel  : 'Anchovies',
+ *                         name      : 'topping',
+ *                         inputValue: '1',
+ *                         id        : 'checkbox1'
+ *                     }, {
+ *                         boxLabel  : 'Artichoke Hearts',
+ *                         name      : 'topping',
+ *                         inputValue: '2',
+ *                         checked   : true,
+ *                         id        : 'checkbox2'
+ *                     }, {
+ *                         boxLabel  : 'Bacon',
+ *                         name      : 'topping',
+ *                         inputValue: '3',
+ *                         id        : 'checkbox3'
+ *                     }
+ *                 ]
+ *             }
+ *         ],
+ *         bbar: [
+ *             {
+ *                 text: 'Select Bacon',
+ *                 handler: function() {
+ *                     Ext.getCmp('checkbox3').setValue(true);
+ *                 }
+ *             },
+ *             '-',
+ *             {
+ *                 text: 'Select All',
+ *                 handler: function() {
+ *                     Ext.getCmp('checkbox1').setValue(true);
+ *                     Ext.getCmp('checkbox2').setValue(true);
+ *                     Ext.getCmp('checkbox3').setValue(true);
+ *                 }
+ *             },
+ *             {
+ *                 text: 'Deselect All',
+ *                 handler: function() {
+ *                     Ext.getCmp('checkbox1').setValue(false);
+ *                     Ext.getCmp('checkbox2').setValue(false);
+ *                     Ext.getCmp('checkbox3').setValue(false);
+ *                 }
+ *             }
+ *         ],
+ *         renderTo: Ext.getBody()
+ *     });
  */
-Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
-    <div id="cfg-Ext.form.Checkbox-focusClass"></div>/**
-     * @cfg {String} focusClass The CSS class to use when the checkbox receives focus (defaults to undefined)
+Ext.define('Ext.form.field.Checkbox', {
+    extend: 'Ext.form.field.Base',
+    alias: ['widget.checkboxfield', 'widget.checkbox'],
+    alternateClassName: 'Ext.form.Checkbox',
+    requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'],
+
+    // note: {id} here is really {inputId}, but {cmpId} is available
+    fieldSubTpl: [
+        '&lt;tpl if=&quot;boxLabel &amp;&amp; boxLabelAlign == \'before\'&quot;&gt;',
+            '&lt;label id=&quot;{cmpId}-boxLabelEl&quot; class=&quot;{boxLabelCls} {boxLabelCls}-{boxLabelAlign}&quot; for=&quot;{id}&quot;&gt;{boxLabel}&lt;/label&gt;',
+        '&lt;/tpl&gt;',
+        // Creates not an actual checkbox, but a button which is given aria role=&quot;checkbox&quot; and
+        // styled with a custom checkbox image. This allows greater control and consistency in
+        // styling, and using a button allows it to gain focus and handle keyboard nav properly.
+        '&lt;input type=&quot;button&quot; id=&quot;{id}&quot; ',
+            '&lt;tpl if=&quot;tabIdx&quot;&gt;tabIndex=&quot;{tabIdx}&quot; &lt;/tpl&gt;',
+            'class=&quot;{fieldCls} {typeCls}&quot; autocomplete=&quot;off&quot; hidefocus=&quot;true&quot; /&gt;',
+        '&lt;tpl if=&quot;boxLabel &amp;&amp; boxLabelAlign == \'after\'&quot;&gt;',
+            '&lt;label id=&quot;{cmpId}-boxLabelEl&quot; class=&quot;{boxLabelCls} {boxLabelCls}-{boxLabelAlign}&quot; for=&quot;{id}&quot;&gt;{boxLabel}&lt;/label&gt;',
+        '&lt;/tpl&gt;',
+        {
+            disableFormats: true,
+            compiled: true
+        }
+    ],
+
+    isCheckbox: true,
+
+<span id='Ext-form-field-Checkbox-cfg-focusCls'>    /**
+</span>     * @cfg {String} [focusCls='x-form-cb-focus']
+     * The CSS class to use when the checkbox receives focus
      */
-    focusClass : undefined,
-    <div id="cfg-Ext.form.Checkbox-fieldClass"></div>/**
-     * @cfg {String} fieldClass The default CSS class for the checkbox (defaults to 'x-form-field')
+    focusCls: Ext.baseCSSPrefix + 'form-cb-focus',
+
+<span id='Ext-form-field-Checkbox-cfg-fieldCls'>    /**
+</span>     * @cfg {String} [fieldCls='x-form-field']
+     * The default CSS class for the checkbox
      */
-    fieldClass : 'x-form-field',
-    <div id="cfg-Ext.form.Checkbox-checked"></div>/**
-     * @cfg {Boolean} checked <tt>true</tt> if the checkbox should render initially checked (defaults to <tt>false</tt>)
+
+<span id='Ext-form-field-Checkbox-cfg-fieldBodyCls'>    /**
+</span>     * @cfg {String} [fieldBodyCls='x-form-cb-wrap']
+     * An extra CSS class to be applied to the body content element in addition to {@link #fieldBodyCls}.
+     * .
      */
-    checked : false,
-    <div id="cfg-Ext.form.Checkbox-autoCreate"></div>/**
-     * @cfg {String/Object} autoCreate A DomHelper element spec, or true for a default element spec (defaults to
-     * {tag: 'input', type: 'checkbox', autocomplete: 'off'})
+    fieldBodyCls: Ext.baseCSSPrefix + 'form-cb-wrap',
+
+<span id='Ext-form-field-Checkbox-cfg-checked'>    /**
+</span>     * @cfg {Boolean} checked
+     * true if the checkbox should render initially checked
      */
-    defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
-    <div id="cfg-Ext.form.Checkbox-boxLabel"></div>/**
-     * @cfg {String} boxLabel The text that appears beside the checkbox
+    checked: false,
+
+<span id='Ext-form-field-Checkbox-cfg-checkedCls'>    /**
+</span>     * @cfg {String} [checkedCls='x-form-cb-checked']
+     * The CSS class added to the component's main element when it is in the checked state.
+     */
+    checkedCls: Ext.baseCSSPrefix + 'form-cb-checked',
+
+<span id='Ext-form-field-Checkbox-cfg-boxLabel'>    /**
+</span>     * @cfg {String} boxLabel
+     * An optional text label that will appear next to the checkbox. Whether it appears before or after the checkbox is
+     * determined by the {@link #boxLabelAlign} config.
+     */
+
+<span id='Ext-form-field-Checkbox-cfg-boxLabelCls'>    /**
+</span>     * @cfg {String} [boxLabelCls='x-form-cb-label']
+     * The CSS class to be applied to the {@link #boxLabel} element
+     */
+    boxLabelCls: Ext.baseCSSPrefix + 'form-cb-label',
+
+<span id='Ext-form-field-Checkbox-cfg-boxLabelAlign'>    /**
+</span>     * @cfg {String} boxLabelAlign
+     * The position relative to the checkbox where the {@link #boxLabel} should appear. Recognized values are 'before'
+     * and 'after'.
+     */
+    boxLabelAlign: 'after',
+
+<span id='Ext-form-field-Checkbox-cfg-inputValue'>    /**
+</span>     * @cfg {String} inputValue
+     * The value that should go into the generated input element's value attribute and should be used as the parameter
+     * value when submitting as part of a form.
      */
-    <div id="cfg-Ext.form.Checkbox-inputValue"></div>/**
-     * @cfg {String} inputValue The value that should go into the generated input element's value attribute
+    inputValue: 'on',
+
+<span id='Ext-form-field-Checkbox-cfg-uncheckedValue'>    /**
+</span>     * @cfg {String} uncheckedValue
+     * If configured, this will be submitted as the checkbox's value during form submit if the checkbox is unchecked. By
+     * default this is undefined, which results in nothing being submitted for the checkbox field when the form is
+     * submitted (the default behavior of HTML checkboxes).
      */
-    <div id="cfg-Ext.form.Checkbox-handler"></div>/**
-     * @cfg {Function} handler A function called when the {@link #checked} value changes (can be used instead of 
-     * handling the check event). The handler is passed the following parameters:
-     * <div class="mdetail-params"><ul>
-     * <li><b>checkbox</b> : Ext.form.Checkbox<div class="sub-desc">The Checkbox being toggled.</div></li>
-     * <li><b>checked</b> : Boolean<div class="sub-desc">The new checked state of the checkbox.</div></li>
-     * </ul></div>
+
+<span id='Ext-form-field-Checkbox-cfg-handler'>    /**
+</span>     * @cfg {Function} handler
+     * A function called when the {@link #checked} value changes (can be used instead of handling the {@link #change
+     * change event}).
+     * @cfg {Ext.form.field.Checkbox} handler.checkbox The Checkbox being toggled.
+     * @cfg {Boolean} handler.checked The new checked state of the checkbox.
      */
-    <div id="cfg-Ext.form.Checkbox-scope"></div>/**
-     * @cfg {Object} scope An object to use as the scope ('this' reference) of the {@link #handler} function
-     * (defaults to this Checkbox).
+
+<span id='Ext-form-field-Checkbox-cfg-scope'>    /**
+</span>     * @cfg {Object} scope
+     * An object to use as the scope ('this' reference) of the {@link #handler} function (defaults to this Checkbox).
      */
 
+    // private overrides
+    checkChangeEvents: [],
+    inputType: 'checkbox',
+    ariaRole: 'checkbox',
+
     // private
-    actionMode : 'wrap',
-    
-       // private
-    initComponent : function(){
-        Ext.form.Checkbox.superclass.initComponent.call(this);
-        this.addEvents(
-            <div id="event-Ext.form.Checkbox-check"></div>/**
-             * @event check
-             * Fires when the checkbox is checked or unchecked.
-             * @param {Ext.form.Checkbox} this This checkbox
-             * @param {Boolean} checked The new checked value
-             */
-            'check'
-        );
+    onRe: /^on$/i,
+
+    initComponent: function(){
+        this.callParent(arguments);
+        this.getManager().add(this);
     },
 
-    // private
-    onResize : function(){
-        Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
-        if(!this.boxLabel && !this.fieldLabel){
-            this.el.alignTo(this.wrap, 'c-c');
-        }
+    initValue: function() {
+        var me = this,
+            checked = !!me.checked;
+
+<span id='Ext-form-field-Checkbox-property-originalValue'>        /**
+</span>         * @property {Object} originalValue
+         * The original value of the field as configured in the {@link #checked} configuration, or as loaded by the last
+         * form load operation if the form's {@link Ext.form.Basic#trackResetOnLoad trackResetOnLoad} setting is `true`.
+         */
+        me.originalValue = me.lastValue = checked;
+
+        // Set the initial checked state
+        me.setValue(checked);
     },
 
     // private
-    initEvents : function(){
-        Ext.form.Checkbox.superclass.initEvents.call(this);
-        this.mon(this.el, {
-            scope: this,
-            click: this.onClick,
-            change: this.onClick
+    onRender : function(ct, position) {
+        var me = this;
+
+<span id='Ext-form-field-Checkbox-property-boxLabelEl'>        /**
+</span>         * @property {Ext.Element} boxLabelEl
+         * A reference to the label element created for the {@link #boxLabel}. Only present if the component has been
+         * rendered and has a boxLabel configured.
+         */
+        me.addChildEls('boxLabelEl');
+
+        Ext.applyIf(me.subTplData, {
+            boxLabel: me.boxLabel,
+            boxLabelCls: me.boxLabelCls,
+            boxLabelAlign: me.boxLabelAlign
         });
+
+        me.callParent(arguments);
+    },
+
+    initEvents: function() {
+        var me = this;
+        me.callParent();
+        me.mon(me.inputEl, 'click', me.onBoxClick, me);
+    },
+
+<span id='Ext-form-field-Checkbox-method-onBoxClick'>    /**
+</span>     * @private Handle click on the checkbox button
+     */
+    onBoxClick: function(e) {
+        var me = this;
+        if (!me.disabled &amp;&amp; !me.readOnly) {
+            this.setValue(!this.checked);
+        }
     },
 
-    <div id="method-Ext.form.Checkbox-markInvalid"></div>/**
-     * @hide
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
-     * @method
+<span id='Ext-form-field-Checkbox-method-getRawValue'>    /**
+</span>     * Returns the checked state of the checkbox.
+     * @return {Boolean} True if checked, else false
      */
-    markInvalid : Ext.emptyFn,
-    <div id="method-Ext.form.Checkbox-clearInvalid"></div>/**
-     * @hide
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
-     * @method
+    getRawValue: function() {
+        return this.checked;
+    },
+
+<span id='Ext-form-field-Checkbox-method-getValue'>    /**
+</span>     * Returns the checked state of the checkbox.
+     * @return {Boolean} True if checked, else false
      */
-    clearInvalid : Ext.emptyFn,
+    getValue: function() {
+        return this.checked;
+    },
 
-    // private
-    onRender : function(ct, position){
-        Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
-        if(this.inputValue !== undefined){
-            this.el.dom.value = this.inputValue;
-        }
-        this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
-        if(this.boxLabel){
-            this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
-        }
-        if(this.checked){
-            this.setValue(true);
-        }else{
-            this.checked = this.el.dom.checked;
-        }
-        // Need to repaint for IE, otherwise positioning is broken
-        if(Ext.isIE){
-            this.wrap.repaint();
+<span id='Ext-form-field-Checkbox-method-getSubmitValue'>    /**
+</span>     * Returns the submit value for the checkbox which can be used when submitting forms.
+     * @return {Boolean/Object} True if checked; otherwise either the {@link #uncheckedValue} or null.
+     */
+    getSubmitValue: function() {
+        var unchecked = this.uncheckedValue,
+            uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null;
+        return this.checked ? this.inputValue : uncheckedVal;
+    },
+
+<span id='Ext-form-field-Checkbox-method-setRawValue'>    /**
+</span>     * Sets the checked state of the checkbox.
+     *
+     * @param {Boolean/String/Number} value The following values will check the checkbox:
+     * `true, 'true', '1', 1, or 'on'`, as well as a String that matches the {@link #inputValue}.
+     * Any other value will uncheck the checkbox.
+     * @return {Boolean} the new checked state of the checkbox
+     */
+    setRawValue: function(value) {
+        var me = this,
+            inputEl = me.inputEl,
+            inputValue = me.inputValue,
+            checked = (value === true || value === 'true' || value === '1' || value === 1 ||
+                (((Ext.isString(value) || Ext.isNumber(value)) &amp;&amp; inputValue) ? value == inputValue : me.onRe.test(value)));
+
+        if (inputEl) {
+            inputEl.dom.setAttribute('aria-checked', checked);
+            me[checked ? 'addCls' : 'removeCls'](me.checkedCls);
         }
-        this.resizeEl = this.positionEl = this.wrap;
+
+        me.checked = me.rawValue = checked;
+        return checked;
     },
 
-    // private
-    onDestroy : function(){
-        Ext.destroy(this.wrap);
-        Ext.form.Checkbox.superclass.onDestroy.call(this);
+<span id='Ext-form-field-Checkbox-method-setValue'>    /**
+</span>     * Sets the checked state of the checkbox, and invokes change detection.
+     * @param {Boolean/String} checked The following values will check the checkbox: `true, 'true', '1', or 'on'`, as
+     * well as a String that matches the {@link #inputValue}. Any other value will uncheck the checkbox.
+     * @return {Ext.form.field.Checkbox} this
+     */
+    setValue: function(checked) {
+        var me = this;
+
+        // If an array of strings is passed, find all checkboxes in the group with the same name as this
+        // one and check all those whose inputValue is in the array, unchecking all the others. This is to
+        // facilitate setting values from Ext.form.Basic#setValues, but is not publicly documented as we
+        // don't want users depending on this behavior.
+        if (Ext.isArray(checked)) {
+            me.getManager().getByName(me.name).each(function(cb) {
+                cb.setValue(Ext.Array.contains(checked, cb.inputValue));
+            });
+        } else {
+            me.callParent(arguments);
+        }
+
+        return me;
     },
 
     // private
-    initValue : function() {
-        this.originalValue = this.getValue();
+    valueToRaw: function(value) {
+        // No extra conversion for checkboxes
+        return value;
     },
 
-    <div id="method-Ext.form.Checkbox-getValue"></div>/**
-     * Returns the checked state of the checkbox.
-     * @return {Boolean} True if checked, else false
+<span id='Ext-form-field-Checkbox-method-onChange'>    /**
+</span>     * @private
+     * Called when the checkbox's checked state changes. Invokes the {@link #handler} callback
+     * function if specified.
      */
-    getValue : function(){
-        if(this.rendered){
-            return this.el.dom.checked;
+    onChange: function(newVal, oldVal) {
+        var me = this,
+            handler = me.handler;
+        if (handler) {
+            handler.call(me.scope || me, me, newVal);
         }
-        return this.checked;
+        me.callParent(arguments);
     },
 
-       // private
-    onClick : function(){
-        if(this.el.dom.checked != this.checked){
-            this.setValue(this.el.dom.checked);
-        }
+    // inherit docs
+    beforeDestroy: function(){
+        this.callParent();
+        this.getManager().removeAtKey(this.id);
     },
 
-    <div id="method-Ext.form.Checkbox-setValue"></div>/**
-     * Sets the checked state of the checkbox, fires the 'check' event, and calls a
-     * <code>{@link #handler}</code> (if configured).
-     * @param {Boolean/String} checked The following values will check the checkbox:
-     * <code>true, 'true', '1', or 'on'</code>. Any other value will uncheck the checkbox.
-     * @return {Ext.form.Field} this
-     */
-    setValue : function(v){
-        var checked = this.checked ;
-        this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
-        if(this.rendered){
-            this.el.dom.checked = this.checked;
-            this.el.dom.defaultChecked = this.checked;
+    // inherit docs
+    getManager: function() {
+        return Ext.form.CheckboxManager;
+    },
+
+    onEnable: function() {
+        var me = this,
+            inputEl = me.inputEl;
+        me.callParent();
+        if (inputEl) {
+            // Can still be disabled if the field is readOnly
+            inputEl.dom.disabled = me.readOnly;
         }
-        if(checked != this.checked){
-            this.fireEvent('check', this, this.checked);
-            if(this.handler){
-                this.handler.call(this.scope || this, this, this.checked);
-            }
+    },
+
+    setReadOnly: function(readOnly) {
+        var me = this,
+            inputEl = me.inputEl;
+        if (inputEl) {
+            // Set the button to disabled when readonly
+            inputEl.dom.disabled = readOnly || me.disabled;
         }
-        return this;
+        me.readOnly = readOnly;
+    },
+
+    // Calculates and returns the natural width of the bodyEl. It's possible that the initial rendering will
+    // cause the boxLabel to wrap and give us a bad width, so we must prevent wrapping while measuring.
+    getBodyNaturalWidth: function() {
+        var me = this,
+            bodyEl = me.bodyEl,
+            ws = 'white-space',
+            width;
+        bodyEl.setStyle(ws, 'nowrap');
+        width = bodyEl.getWidth();
+        bodyEl.setStyle(ws, '');
+        return width;
     }
+
 });
-Ext.reg('checkbox', Ext.form.Checkbox);
-</pre>    \r
-</body>\r
-</html>
\ No newline at end of file
+</pre>
+</body>
+</html>