3 * Copyright(c) 2006-2010 Ext JS, Inc.
5 * http://www.extjs.com/license
8 * @class Ext.CycleButton
9 * @extends Ext.SplitButton
10 * A specialized SplitButton that contains a menu of {@link Ext.menu.CheckItem} elements. The button automatically
11 * cycles through each menu item on click, raising the button's {@link #change} event (or calling the button's
12 * {@link #changeHandler} function, if supplied) for the active menu item. Clicking on the arrow section of the
13 * button displays the dropdown menu just like a normal SplitButton. Example usage:
15 var btn = new Ext.CycleButton({
17 prependText: 'View as ',
26 changeHandler:function(btn, item){
27 Ext.Msg.alert('Change View', item.text);
32 * Create a new split button
33 * @param {Object} config The config object
36 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
38 * @cfg {Array} items An array of {@link Ext.menu.CheckItem} <b>config</b> objects to be used when creating the
39 * button's menu items (e.g., {text:'Foo', iconCls:'foo-icon'})
42 * @cfg {Boolean} showText True to display the active item's text as the button text (defaults to false)
45 * @cfg {String} prependText A static string to prepend before the active item's text when displayed as the
46 * button's text (only applies when showText = true, defaults to '')
49 * @cfg {Function} changeHandler A callback function that will be invoked each time the active menu
50 * item in the button's menu has changed. If this callback is not supplied, the SplitButton will instead
51 * fire the {@link #change} event on active item change. The changeHandler function will be called with the
52 * following argument list: (SplitButton this, Ext.menu.CheckItem item)
55 * @cfg {String} forceIcon A css class which sets an image to be used as the static icon for this button. This
56 * icon will always be displayed regardless of which item is selected in the dropdown list. This overrides the
57 * default behavior of changing the button's icon to match the selected item's icon on change.
62 * The {@link Ext.menu.Menu Menu} object used to display the {@link Ext.menu.CheckItem CheckItems} representing the available choices.
66 getItemText : function(item){
67 if(item && this.showText === true){
70 text += this.prependText;
79 * Sets the button's active menu item.
80 * @param {Ext.menu.CheckItem} item The item to activate
81 * @param {Boolean} suppressEvent True to prevent the button's change event from firing (defaults to false)
83 setActiveItem : function(item, suppressEvent){
84 if(!Ext.isObject(item)){
85 item = this.menu.getComponent(item);
89 this.text = this.getItemText(item);
90 this.iconCls = item.iconCls;
92 var t = this.getItemText(item);
96 this.setIconClass(item.iconCls);
98 this.activeItem = item;
100 item.setChecked(true, false);
103 this.setIconClass(this.forceIcon);
106 this.fireEvent('change', this, item);
112 * Gets the currently active menu item.
113 * @return {Ext.menu.CheckItem} The active item
115 getActiveItem : function(){
116 return this.activeItem;
120 initComponent : function(){
124 * Fires after the button's active menu item has changed. Note that if a {@link #changeHandler} function
125 * is set on this CycleButton, it will be called instead on active item change and this change event will
127 * @param {Ext.CycleButton} this
128 * @param {Ext.menu.CheckItem} item The menu item that was selected
133 if(this.changeHandler){
134 this.on('change', this.changeHandler, this.scope||this);
135 delete this.changeHandler;
138 this.itemCount = this.items.length;
140 this.menu = {cls:'x-cycle-menu', items:[]};
142 Ext.each(this.items, function(item, i){
144 group: item.group || this.id,
146 checkHandler: this.checkHandler,
148 checked: item.checked || false
150 this.menu.items.push(item);
155 Ext.CycleButton.superclass.initComponent.call(this);
156 this.on('click', this.toggleSelected, this);
157 this.setActiveItem(checked, true);
161 checkHandler : function(item, pressed){
163 this.setActiveItem(item);
168 * This is normally called internally on button click, but can be called externally to advance the button's
169 * active item programmatically to the next one in the menu. If the current item is the last one in the menu
170 * the active item will be set to the first item in the menu.
172 toggleSelected : function(){
175 // layout if we haven't before so the items are active
180 var nextIdx, checkItem;
181 for (var i = 1; i < this.itemCount; i++) {
182 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
183 // check the potential item
184 checkItem = m.items.itemAt(nextIdx);
185 // if its not disabled then check it.
186 if (!checkItem.disabled) {
187 checkItem.setChecked(true);
193 Ext.reg('cycle', Ext.CycleButton);