Upgrade to ExtJS 3.2.0 - Released 03/30/2010
[extjs.git] / src / widgets / SplitButton.js
1 /*!
2  * Ext JS Library 3.2.0
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 /**
8  * @class Ext.SplitButton
9  * @extends Ext.Button
10  * A split button that provides a built-in dropdown arrow that can fire an event separately from the default
11  * click event of the button.  Typically this would be used to display a dropdown menu that provides additional
12  * options to the primary button action, but any custom handler can provide the arrowclick implementation.  Example usage:
13  * <pre><code>
14 // display a dropdown menu:
15 new Ext.SplitButton({
16         renderTo: 'button-ct', // the container id
17         text: 'Options',
18         handler: optionsHandler, // handle a click on the button itself
19         menu: new Ext.menu.Menu({
20         items: [
21                 // these items will render as dropdown menu items when the arrow is clicked:
22                 {text: 'Item 1', handler: item1Handler},
23                 {text: 'Item 2', handler: item2Handler}
24         ]
25         })
26 });
27
28 // Instead of showing a menu, you provide any type of custom
29 // functionality you want when the dropdown arrow is clicked:
30 new Ext.SplitButton({
31         renderTo: 'button-ct',
32         text: 'Options',
33         handler: optionsHandler,
34         arrowHandler: myCustomHandler
35 });
36 </code></pre>
37  * @cfg {Function} arrowHandler A function called when the arrow button is clicked (can be used instead of click event)
38  * @cfg {String} arrowTooltip The title attribute of the arrow
39  * @constructor
40  * Create a new menu button
41  * @param {Object} config The config object
42  * @xtype splitbutton
43  */
44 Ext.SplitButton = Ext.extend(Ext.Button, {
45         // private
46     arrowSelector : 'em',
47     split: true,
48
49     // private
50     initComponent : function(){
51         Ext.SplitButton.superclass.initComponent.call(this);
52         /**
53          * @event arrowclick
54          * Fires when this button's arrow is clicked
55          * @param {MenuButton} this
56          * @param {EventObject} e The click event
57          */
58         this.addEvents("arrowclick");
59     },
60
61     // private
62     onRender : function(){
63         Ext.SplitButton.superclass.onRender.apply(this, arguments);
64         if(this.arrowTooltip){
65             this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
66         }
67     },
68
69     /**
70      * Sets this button's arrow click handler.
71      * @param {Function} handler The function to call when the arrow is clicked
72      * @param {Object} scope (optional) Scope for the function passed above
73      */
74     setArrowHandler : function(handler, scope){
75         this.arrowHandler = handler;
76         this.scope = scope;
77     },
78
79     getMenuClass : function(){
80         return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
81     },
82
83     isClickOnArrow : function(e){
84         if (this.arrowAlign != 'bottom') {
85             var visBtn = this.el.child('em.x-btn-split');
86             var right = visBtn.getRegion().right - visBtn.getPadding('r');
87             return e.getPageX() > right;
88         } else {
89             return e.getPageY() > this.btnEl.getRegion().bottom;
90         }
91     },
92
93     // private
94     onClick : function(e, t){
95         e.preventDefault();
96         if(!this.disabled){
97             if(this.isClickOnArrow(e)){
98                 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
99                     this.showMenu();
100                 }
101                 this.fireEvent("arrowclick", this, e);
102                 if(this.arrowHandler){
103                     this.arrowHandler.call(this.scope || this, this, e);
104                 }
105             }else{
106                 if(this.enableToggle){
107                     this.toggle();
108                 }
109                 this.fireEvent("click", this, e);
110                 if(this.handler){
111                     this.handler.call(this.scope || this, this, e);
112                 }
113             }
114         }
115     },
116
117     // private
118     isMenuTriggerOver : function(e){
119         return this.menu && e.target.tagName == this.arrowSelector;
120     },
121
122     // private
123     isMenuTriggerOut : function(e, internal){
124         return this.menu && e.target.tagName != this.arrowSelector;
125     }
126 });
127
128 Ext.reg('splitbutton', Ext.SplitButton);