/* * 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);