Upgrade to ExtJS 3.2.1 - Released 04/27/2010
[extjs.git] / docs / source / Button.html
index c51d436..02a91e7 100644 (file)
@@ -1,13 +1,14 @@
 <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>
 </head>
 <body  onload="prettyPrint();">
     <pre class="prettyprint lang-js">/*!
- * Ext JS Library 3.0.3
- * Copyright(c) 2006-2009 Ext JS, LLC
+ * Ext JS Library 3.2.1
+ * Copyright(c) 2006-2010 Ext JS, Inc.
  * licensing@extjs.com
  * http://www.extjs.com/license
  */
@@ -72,7 +73,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @cfg {Function} toggleHandler
      * Function called when a Button with {@link #enableToggle} set to true is clicked. Two arguments are passed:<ul class="mdetail-params">
      * <li><b>button</b> : Ext.Button<div class="sub-desc">this Button object</div></li>
-     * <li><b>state</b> : Boolean<div class="sub-desc">The next state if the Button, true means pressed.</div></li>
+     * <li><b>state</b> : Boolean<div class="sub-desc">The next state of the Button, true means pressed.</div></li>
      * </ul>
      */
     /**
@@ -105,7 +106,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
 
     /**
      * @cfg {String} clickEvent
-     * The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu). 
+     * The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu).
      * Defaults to <tt>'click'</tt>.
      */
     clickEvent : 'click',
@@ -192,6 +193,13 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @type Menu
      * The {@link Ext.menu.Menu Menu} object associated with this Button when configured with the {@link #menu} config option.
      */
+    /**
+     * @cfg {Boolean} autoWidth
+     * By default, if a width is not specified the button will attempt to stretch horizontally to fit its content.
+     * If the button is being managed by a width sizing layout (hbox, fit, anchor), set this to false to prevent
+     * the button from doing this automatic sizing.
+     * Defaults to <tt>undefined</tt>.
+     */
 
     initComponent : function(){
         Ext.Button.superclass.initComponent.call(this);
@@ -265,28 +273,33 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     },
 
 /**
-  * <p>This method returns an object which provides substitution parameters for the {@link #template Template} used
+  * <p>This method returns an Array which provides substitution parameters for the {@link #template Template} used
   * to create this Button's DOM structure.</p>
   * <p>Instances or subclasses which use a different Template to create a different DOM structure may need to provide their
   * own implementation of this method.</p>
   * <p>The default implementation which provides data for the default {@link #template} returns an Array containing the
   * following items:</p><div class="mdetail-params"><ul>
-  * <li>The Button's {@link #text}</li>
   * <li>The &lt;button&gt;'s {@link #type}</li>
-  * <li>The {@link iconCls} applied to the &lt;button&gt; {@link #btnEl element}</li>
-  * <li>The {@link #cls} applied to the Button's main {@link #getEl Element}</li>
-  * <li>A CSS class name controlling the Button's {@link #scale} and {@link #iconAlign icon alignment}</li>
-  * <li>A CSS class name which applies an arrow to the Button if configured with a {@link #menu}</li>
+  * <li>A CSS class name applied to the Button's main &lt;tbody&gt; element which determines the button's scale and icon alignment.</li>
+  * <li>A CSS class to determine the presence and position of an arrow icon. (<code>'x-btn-arrow'</code> or <code>'x-btn-arrow-bottom'</code> or <code>''</code>)</li>
+  * <li>The {@link #cls} CSS class name applied to the button's wrapping &lt;table&gt; element.</li>
+  * <li>The Component id which is applied to the button's wrapping &lt;table&gt; element.</li>
   * </ul></div>
-  * @return {Object} Substitution data for a Template.
+  * @return {Array} Substitution data for a Template.
  */
     getTemplateArgs : function(){
-        var cls = (this.cls || '');
-        cls += (this.iconCls || this.icon) ? (this.text ? ' x-btn-text-icon' : ' x-btn-icon') : ' x-btn-noicon';
-        if(this.pressed){
-            cls += ' x-btn-pressed';
+        return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
+    },
+
+    // private
+    setButtonClass : function(){
+        if(this.useSetClass){
+            if(!Ext.isEmpty(this.oldCls)){
+                this.el.removeClass([this.oldCls, 'x-btn-pressed']);
+            }
+            this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
+            this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
         }
-        return [this.text || '&#160;', this.type, this.iconCls || '', cls, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass()];
     },
 
     // protected
@@ -300,11 +313,11 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(!Ext.Button.buttonTemplate){
                 // hideous table template
                 Ext.Button.buttonTemplate = new Ext.Template(
-                    '<table cellspacing="0" class="x-btn {3}"><tbody class="{4}">',
+                    '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
                     '<tr><td class="x-btn-tl"><i>&#160;</i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i>&#160;</i></td></tr>',
-                    '<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{5}" unselectable="on"><button class="x-btn-text {2}" type="{1}">{0}</button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
+                    '<tr><td class="x-btn-ml"><i>&#160;</i></td><td class="x-btn-mc"><em class="{2}" unselectable="on"><button type="{0}"></button></em></td><td class="x-btn-mr"><i>&#160;</i></td></tr>',
                     '<tr><td class="x-btn-bl"><i>&#160;</i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i>&#160;</i></td></tr>',
-                    "</tbody></table>");
+                    '</tbody></table>');
                 Ext.Button.buttonTemplate.compile();
             }
             this.template = Ext.Button.buttonTemplate;
@@ -338,19 +351,10 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     // private
     initButtonEl : function(btn, btnEl){
         this.el = btn;
-
-        if(this.id){
-            var d = this.el.dom,
-                c = Ext.Element.cache;
-                
-            delete c[d.id];
-            d.id = this.el.id = this.id;
-            c[d.id] = this.el;
-        }
-        if(this.icon){
-            btnEl.setStyle('background-image', 'url(' +this.icon +')');
-        }
-        if(this.tabIndex !== undefined){
+        this.setIcon(this.icon);
+        this.setText(this.text);
+        this.setIconClass(this.iconCls);
+        if(Ext.isDefined(this.tabIndex)){
             btnEl.dom.tabIndex = this.tabIndex;
         }
         if(this.tooltip){
@@ -386,6 +390,9 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     // private
     afterRender : function(){
         Ext.Button.superclass.afterRender.call(this);
+        this.useSetClass = true;
+        this.setButtonClass();
+        this.doc = Ext.getDoc();
         this.doAutoWidth();
     },
 
@@ -396,10 +403,12 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @return {Ext.Button} this
      */
     setIconClass : function(cls){
+        this.iconCls = cls;
         if(this.el){
-            this.btnEl.replaceClass(this.iconCls, cls);
+            this.btnEl.dom.className = '';
+            this.btnEl.addClass(['x-btn-text', cls || '']);
+            this.setButtonClass();
         }
-        this.iconCls = cls;
         return this;
     },
 
@@ -442,22 +451,27 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         if(this.rendered){
             this.clearTip();
         }
-        Ext.destroy(this.menu, this.repeater);
+        if(this.menu && this.destroyMenu !== false) {
+            Ext.destroy(this.menu);
+        }
+        Ext.destroy(this.repeater);
     },
 
     // private
     onDestroy : function(){
-        var doc = Ext.getDoc();
-        doc.un('mouseover', this.monitorMouseOver, this);
-        doc.un('mouseup', this.onMouseUp, this);
         if(this.rendered){
+            this.doc.un('mouseover', this.monitorMouseOver, this);
+            this.doc.un('mouseup', this.onMouseUp, this);
+            delete this.doc;
+            delete this.btnEl;
             Ext.ButtonToggleMgr.unregister(this);
         }
+        Ext.Button.superclass.onDestroy.call(this);
     },
 
     // private
     doAutoWidth : function(){
-        if(this.el && this.text && this.width === undefined){
+        if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
             this.el.setWidth('auto');
             if(Ext.isIE7 && Ext.isStrict){
                 var ib = this.btnEl;
@@ -477,7 +491,8 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     /**
      * Assigns this Button's click handler
      * @param {Function} handler The function to call when the button is clicked
-     * @param {Object} scope (optional) Scope for the function passed in. Defaults to this Button.
+     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function is executed.
+     * Defaults to this Button.
      * @return {Ext.Button} this
      */
     setHandler : function(handler, scope){
@@ -494,12 +509,28 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     setText : function(text){
         this.text = text;
         if(this.el){
-            this.el.child('td.x-btn-mc ' + this.buttonSelector).update(text);
+            this.btnEl.update(text || '&#160;');
+            this.setButtonClass();
         }
         this.doAutoWidth();
         return this;
     },
 
+    /**
+     * Sets the background image (inline style) of the button.  This method also changes
+     * the value of the {@link icon} config internally.
+     * @param {String} icon The path to an image to display in the button
+     * @return {Ext.Button} this
+     */
+    setIcon : function(icon){
+        this.icon = icon;
+        if(this.el){
+            this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
+            this.setButtonClass();
+        }
+        return this;
+    },
+
     /**
      * Gets the text for this Button
      * @return {String} The button text
@@ -531,13 +562,6 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         return this;
     },
 
-    /**
-     * Focus the button
-     */
-    focus : function(){
-        this.btnEl.focus();
-    },
-
     // private
     onDisable : function(){
         this.onDisableChange(true);
@@ -566,6 +590,10 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(this.tooltip){
                 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
             }
+            if(this.menu.isVisible()){
+                this.menu.hide();
+            }
+            this.menu.ownerCt = this;
             this.menu.show(this.el, this.menuAlign);
         }
         return this;
@@ -575,7 +603,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * Hide this button's menu (if it has one)
      */
     hideMenu : function(){
-        if(this.menu){
+        if(this.hasVisibleMenu()){
             this.menu.hide();
         }
         return this;
@@ -586,7 +614,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @return {Boolean}
      */
     hasVisibleMenu : function(){
-        return this.menu && this.menu.isVisible();
+        return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
     },
 
     // private
@@ -601,7 +629,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
                 this.toggle();
             }
-            if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
+            if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
                 this.showMenu();
             }
             this.fireEvent('click', this, e);
@@ -629,7 +657,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             if(!internal){
                 this.el.addClass('x-btn-over');
                 if(!this.monitoringMouseOver){
-                    Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
+                    this.doc.on('mouseover', this.monitorMouseOver, this);
                     this.monitoringMouseOver = true;
                 }
                 this.fireEvent('mouseover', this, e);
@@ -644,7 +672,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     monitorMouseOver : function(e){
         if(e.target != this.el.dom && !e.within(this.el)){
             if(this.monitoringMouseOver){
-                Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
+                this.doc.un('mouseover', this.monitorMouseOver, this);
                 this.monitoringMouseOver = false;
             }
             this.onMouseOut(e);
@@ -660,6 +688,15 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             this.fireEvent('menutriggerout', this, this.menu, e);
         }
     },
+
+    focus : function() {
+        this.btnEl.focus();
+    },
+
+    blur : function() {
+        this.btnEl.blur();
+    },
+
     // private
     onFocus : function(e){
         if(!this.disabled){
@@ -680,27 +717,33 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     onMouseDown : function(e){
         if(!this.disabled && e.button === 0){
             this.getClickEl(e).addClass('x-btn-click');
-            Ext.getDoc().on('mouseup', this.onMouseUp, this);
+            this.doc.on('mouseup', this.onMouseUp, this);
         }
     },
     // private
     onMouseUp : function(e){
         if(e.button === 0){
             this.getClickEl(e, true).removeClass('x-btn-click');
-            Ext.getDoc().un('mouseup', this.onMouseUp, this);
+            this.doc.un('mouseup', this.onMouseUp, this);
         }
     },
     // private
     onMenuShow : function(e){
-        this.ignoreNextClick = 0;
-        this.el.addClass('x-btn-menu-active');
-        this.fireEvent('menushow', this, this.menu);
+        if(this.menu.ownerCt == this){
+            this.menu.ownerCt = this;
+            this.ignoreNextClick = 0;
+            this.el.addClass('x-btn-menu-active');
+            this.fireEvent('menushow', this, this.menu);
+        }
     },
     // private
     onMenuHide : function(e){
-        this.el.removeClass('x-btn-menu-active');
-        this.ignoreNextClick = this.restoreClick.defer(250, this);
-        this.fireEvent('menuhide', this, this.menu);
+        if(this.menu.ownerCt == this){
+            this.el.removeClass('x-btn-menu-active');
+            this.ignoreNextClick = this.restoreClick.defer(250, this);
+            this.fireEvent('menuhide', this, this.menu);
+            delete this.menu.ownerCt;
+        }
     },
 
     // private
@@ -708,11 +751,24 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         this.ignoreNextClick = 0;
     }
 
-
-
     /**
      * @cfg {String} autoEl @hide
      */
+    /**
+     * @cfg {String/Object} html @hide
+     */
+    /**
+     * @cfg {String} contentEl  @hide
+     */
+    /**
+     * @cfg {Mixed} data  @hide
+     */
+    /**
+     * @cfg {Mixed} tpl  @hide
+     */
+    /**
+     * @cfg {String} tplWriteMode  @hide
+     */
 });
 Ext.reg('button', Ext.Button);
 
@@ -772,6 +828,7 @@ Ext.ButtonToggleMgr = function(){
            return null;
        }
    };
-}();</pre>
+}();
+</pre>    
 </body>
 </html>
\ No newline at end of file