CycleButton.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:7k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.1.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.CycleButton
  3.  * @extends Ext.SplitButton
  4.  * A specialized SplitButton that contains a menu of {@link Ext.menu.CheckItem} elements.  The button automatically
  5.  * cycles through each menu item on click, raising the button's {@link #change} event (or calling the button's
  6.  * {@link #changeHandler} function, if supplied) for the active menu item. Clicking on the arrow section of the
  7.  * button displays the dropdown menu just like a normal SplitButton.  Example usage:
  8.  * <pre><code>
  9. var btn = new Ext.CycleButton({
  10.     showText: true,
  11.     prependText: 'View as ',
  12.     items: [{
  13.         text:'text only',
  14.         iconCls:'view-text',
  15.         checked:true
  16.     },{
  17.         text:'HTML',
  18.         iconCls:'view-html'
  19.     }],
  20.     changeHandler:function(btn, item){
  21.         Ext.Msg.alert('Change View', item.text);
  22.     }
  23. });
  24. </code></pre>
  25.  * @constructor
  26.  * Create a new split button
  27.  * @param {Object} config The config object
  28.  * @xtype cycle
  29.  */
  30. Ext.CycleButton = Ext.extend(Ext.SplitButton, {
  31.     /**
  32.      * @cfg {Array} items An array of {@link Ext.menu.CheckItem} <b>config</b> objects to be used when creating the
  33.      * button's menu items (e.g., {text:'Foo', iconCls:'foo-icon'})
  34.      */
  35.     /**
  36.      * @cfg {Boolean} showText True to display the active item's text as the button text (defaults to false)
  37.      */
  38.     /**
  39.      * @cfg {String} prependText A static string to prepend before the active item's text when displayed as the
  40.      * button's text (only applies when showText = true, defaults to '')
  41.      */
  42.     /**
  43.      * @cfg {Function} changeHandler A callback function that will be invoked each time the active menu
  44.      * item in the button's menu has changed.  If this callback is not supplied, the SplitButton will instead
  45.      * fire the {@link #change} event on active item change.  The changeHandler function will be called with the
  46.      * following argument list: (SplitButton this, Ext.menu.CheckItem item)
  47.      */
  48.     /**
  49.      * @cfg {String} forceIcon A css class which sets an image to be used as the static icon for this button.  This
  50.      * icon will always be displayed regardless of which item is selected in the dropdown list.  This overrides the 
  51.      * default behavior of changing the button's icon to match the selected item's icon on change.
  52.      */
  53.     /**
  54.      * @property menu
  55.      * @type Menu
  56.      * The {@link Ext.menu.Menu Menu} object used to display the {@link Ext.menu.CheckItem CheckItems} representing the available choices.
  57.      */
  58.     // private
  59.     getItemText : function(item){
  60.         if(item && this.showText === true){
  61.             var text = '';
  62.             if(this.prependText){
  63.                 text += this.prependText;
  64.             }
  65.             text += item.text;
  66.             return text;
  67.         }
  68.         return undefined;
  69.     },
  70.     /**
  71.      * Sets the button's active menu item.
  72.      * @param {Ext.menu.CheckItem} item The item to activate
  73.      * @param {Boolean} suppressEvent True to prevent the button's change event from firing (defaults to false)
  74.      */
  75.     setActiveItem : function(item, suppressEvent){
  76.         if(!Ext.isObject(item)){
  77.             item = this.menu.getComponent(item);
  78.         }
  79.         if(item){
  80.             if(!this.rendered){
  81.                 this.text = this.getItemText(item);
  82.                 this.iconCls = item.iconCls;
  83.             }else{
  84.                 var t = this.getItemText(item);
  85.                 if(t){
  86.                     this.setText(t);
  87.                 }
  88.                 this.setIconClass(item.iconCls);
  89.             }
  90.             this.activeItem = item;
  91.             if(!item.checked){
  92.                 item.setChecked(true, true);
  93.             }
  94.             if(this.forceIcon){
  95.                 this.setIconClass(this.forceIcon);
  96.             }
  97.             if(!suppressEvent){
  98.                 this.fireEvent('change', this, item);
  99.             }
  100.         }
  101.     },
  102.     /**
  103.      * Gets the currently active menu item.
  104.      * @return {Ext.menu.CheckItem} The active item
  105.      */
  106.     getActiveItem : function(){
  107.         return this.activeItem;
  108.     },
  109.     // private
  110.     initComponent : function(){
  111.         this.addEvents(
  112.             /**
  113.              * @event change
  114.              * Fires after the button's active menu item has changed.  Note that if a {@link #changeHandler} function
  115.              * is set on this CycleButton, it will be called instead on active item change and this change event will
  116.              * not be fired.
  117.              * @param {Ext.CycleButton} this
  118.              * @param {Ext.menu.CheckItem} item The menu item that was selected
  119.              */
  120.             "change"
  121.         );
  122.         if(this.changeHandler){
  123.             this.on('change', this.changeHandler, this.scope||this);
  124.             delete this.changeHandler;
  125.         }
  126.         this.itemCount = this.items.length;
  127.         this.menu = {cls:'x-cycle-menu', items:[]};
  128.         var checked;
  129.         Ext.each(this.items, function(item, i){
  130.             Ext.apply(item, {
  131.                 group: item.group || this.id,
  132.                 itemIndex: i,
  133.                 checkHandler: this.checkHandler,
  134.                 scope: this,
  135.                 checked: item.checked || false
  136.             });
  137.             this.menu.items.push(item);
  138.             if(item.checked){
  139.                 checked = item;
  140.             }
  141.         }, this);
  142.         this.setActiveItem(checked, true);
  143.         Ext.CycleButton.superclass.initComponent.call(this);
  144.         this.on('click', this.toggleSelected, this);
  145.     },
  146.     // private
  147.     checkHandler : function(item, pressed){
  148.         if(pressed){
  149.             this.setActiveItem(item);
  150.         }
  151.     },
  152.     /**
  153.      * This is normally called internally on button click, but can be called externally to advance the button's
  154.      * active item programmatically to the next one in the menu.  If the current item is the last one in the menu
  155.      * the active item will be set to the first item in the menu.
  156.      */
  157.     toggleSelected : function(){
  158.         var m = this.menu;
  159.         m.render();
  160.         // layout if we haven't before so the items are active
  161.         if(!m.hasLayout){
  162.             m.doLayout();
  163.         }
  164.         
  165.         var nextIdx, checkItem;
  166.         for (var i = 1; i < this.itemCount; i++) {
  167.             nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
  168.             // check the potential item
  169.             checkItem = m.items.itemAt(nextIdx);
  170.             // if its not disabled then check it.
  171.             if (!checkItem.disabled) {
  172.                 checkItem.setChecked(true);
  173.                 break;
  174.             }
  175.         }
  176.     }
  177. });
  178. Ext.reg('cycle', Ext.CycleButton);