/* * Ext JS Library 2.0 Copyright(c) 2006-2007, Ext JS, LLC. licensing@extjs.com * * http://extjs.com/license */ /** * @class Ext.CycleButton * @extends Ext.SplitButton A specialized SplitButton that contains a menu of * {@link Ext.menu.CheckItem} elements. The button automatically cycles * through each menu item on click, raising the button's * {@link #change} event (or calling the button's * {@link #changeHandler} function, if supplied) for the active menu * item. Clicking on the arrow section of the button displays the * dropdown menu just like a normal SplitButton. Example usage: * *

 * var btn = new Ext.CycleButton({
 * 			showText : true,
 * 			prependText : 'View as ',
 * 			items : [{
 * 						text : 'text only',
 * 						iconCls : 'view-text',
 * 						checked : true
 * 					}, {
 * 						text : 'HTML',
 * 						iconCls : 'view-html'
 * 					}],
 * 			changeHandler : function(btn, item) {
 * 				Ext.Msg.alert('Change View', item.text);
 * 			}
 * 		});
 * 
* * @constructor Create a new split button * @param {Object} * config The config object */ Ext.CycleButton = Ext.extend(Ext.SplitButton, { /** * @cfg {Array} items An array of {@link Ext.menu.CheckItem} * config objects to be used when creating the button's * menu items (e.g., {text:'Foo', iconCls:'foo-icon'}) */ /** * @cfg {Boolean} showText True to display the active item's text as * the button text (defaults to false) */ /** * @cfg {String} prependText A static string to prepend before the * active item's text when displayed as the button's text (only * applies when showText = true, defaults to '') */ /** * @cfg {Function} changeHandler A callback function that will be * invoked each time the active menu item in the button's menu * has changed. If this callback is not supplied, the * SplitButton will instead fire the {@link #change} event on * active item change. The changeHandler function will be * called with the following argument list: (SplitButton this, * Ext.menu.CheckItem item) */ // private getItemText : function(item) { if (item && this.showText === true) { var text = ''; if (this.prependText) { text += this.prependText; } text += item.text; return text; } return undefined; }, /** * Sets the button's active menu item. * * @param {Ext.menu.CheckItem} * item The item to activate * @param {Boolean} * suppressEvent True to prevent the button's change * event from firing (defaults to false) */ setActiveItem : function(item, suppressEvent) { if (item) { if (!this.rendered) { this.text = this.getItemText(item); this.iconCls = item.iconCls; } else { var t = this.getItemText(item); if (t) { this.setText(t); } this.setIconClass(item.iconCls); } this.activeItem = item; if (!suppressEvent) { this.fireEvent('change', this, item); } } }, /** * Gets the currently active menu item. * * @return {Ext.menu.CheckItem} The active item */ getActiveItem : function() { return this.activeItem; }, // private initComponent : function() { this.addEvents( /** * @event change Fires after the button's active menu * item has changed. Note that if a * {@link #changeHandler} function is set on this * CycleButton, it will be called instead on * active item change and this change event will * not be fired. * @param {Ext.CycleButton} * this * @param {Ext.menu.CheckItem} * item The menu item that was selected */ "change"); if (this.changeHandler) { this.on('change', this.changeHandler, this.scope || this); delete this.changeHandler; } this.itemCount = this.items.length; this.menu = { cls : 'x-cycle-menu', items : [] }; var checked; for (var i = 0, len = this.itemCount; i < len; i++) { var item = this.items[i]; item.group = item.group || this.id; item.itemIndex = i; item.checkHandler = this.checkHandler; item.scope = this; item.checked = item.checked || false; this.menu.items.push(item); if (item.checked) { checked = item; } } this.setActiveItem(checked, true); Ext.CycleButton.superclass.initComponent.call(this); this.on('click', this.toggleSelected, this); }, // private checkHandler : function(item, pressed) { if (pressed) { this.setActiveItem(item); } }, /** * This is normally called internally on button click, but can be * called externally to advance the button's active item * programmatically to the next one in the menu. If the current item * is the last one in the menu the active item will be set to the * first item in the menu. */ toggleSelected : function() { this.menu.render(); var nextIdx, checkItem; for (var i = 1; i < this.itemCount; i++) { nextIdx = (this.activeItem.itemIndex + i) % this.itemCount; // check the potential item checkItem = this.menu.items.itemAt(nextIdx); // if its not disabled then check it. if (!checkItem.disabled) { checkItem.setChecked(true); break; } } } }); Ext.reg('cycle', Ext.CycleButton);