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