pkg-toolbars-debug.js
上传用户:shuoshiled
上传日期:2018-01-28
资源大小:10124k
文件大小:44k
源码类别:

中间件编程

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.0.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.layout.ToolbarLayout
  3.  * @extends Ext.layout.ContainerLayout
  4.  * Layout manager implicitly used by Ext.Toolbar.
  5.  */
  6. Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
  7.     monitorResize : true,
  8.     triggerWidth : 18,
  9.     lastOverflow : false,
  10.     noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
  11.     // private
  12.     onLayout : function(ct, target){
  13.         if(!this.leftTr){
  14.             target.addClass('x-toolbar-layout-ct');
  15.             target.insertHtml('beforeEnd',
  16.                  '<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="left"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
  17.             this.leftTr = target.child('tr.x-toolbar-left-row', true);
  18.             this.rightTr = target.child('tr.x-toolbar-right-row', true);
  19.             this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
  20.         }
  21.         var side = this.leftTr;
  22.         var pos = 0;
  23.         var items = ct.items.items;
  24.         for(var i = 0, len = items.length, c; i < len; i++, pos++) {
  25.             c = items[i];
  26.             if(c.isFill){
  27.                 side = this.rightTr;
  28.                 pos = -1;
  29.             }else if(!c.rendered){
  30.                 c.render(this.insertCell(c, side, pos));
  31.             }else{
  32.                 if(!c.xtbHidden && !this.isValidParent(c, side.childNodes[pos])){
  33.                     var td = this.insertCell(c, side, pos);
  34.                     td.appendChild(c.getDomPositionEl().dom);
  35.                     c.container = Ext.get(td);
  36.                 }
  37.             }
  38.         }
  39.         //strip extra empty cells
  40.         this.cleanup(this.leftTr);
  41.         this.cleanup(this.rightTr);
  42.         this.cleanup(this.extrasTr);
  43.         this.fitToSize(target);
  44.     },
  45.     cleanup : function(row){
  46.         var cn = row.childNodes;
  47.         for(var i = cn.length-1, c; i >= 0 && (c = cn[i]); i--){
  48.             if(!c.firstChild){
  49.                 row.removeChild(c);
  50.             }
  51.         }
  52.     },
  53.     insertCell : function(c, side, pos){
  54.         var td = document.createElement('td');
  55.         td.className='x-toolbar-cell';
  56.         side.insertBefore(td, side.childNodes[pos]||null);
  57.         return td;
  58.     },
  59.     hideItem : function(item){
  60.         var h = (this.hiddens = this.hiddens || []);
  61.         h.push(item);
  62.         item.xtbHidden = true;
  63.         item.xtbWidth = item.getDomPositionEl().dom.parentNode.offsetWidth;
  64.         item.hide();
  65.     },
  66.     unhideItem : function(item){
  67.         item.show();
  68.         item.xtbHidden = false;
  69.         this.hiddens.remove(item);
  70.         if(this.hiddens.length < 1){
  71.             delete this.hiddens;
  72.         }
  73.     },
  74.     getItemWidth : function(c){
  75.         return c.hidden ? (c.xtbWidth || 0) : c.getDomPositionEl().dom.parentNode.offsetWidth;
  76.     },
  77.     fitToSize : function(t){
  78.         if(this.container.enableOverflow === false){
  79.             return;
  80.         }
  81.         var w = t.dom.clientWidth;
  82.         var lw = this.lastWidth || 0;
  83.         this.lastWidth = w;
  84.         var iw = t.dom.firstChild.offsetWidth;
  85.         var clipWidth = w - this.triggerWidth;
  86.         var hideIndex = -1;
  87.         if(iw > w || (this.hiddens && w >= lw)){
  88.             var i, items = this.container.items.items, len = items.length, c;
  89.             var loopWidth = 0;
  90.             for(i = 0; i < len; i++) {
  91.                 c = items[i];
  92.                 if(!c.isFill){
  93.                     loopWidth += this.getItemWidth(c);
  94.                     if(loopWidth > clipWidth){
  95.                         if(!c.xtbHidden){
  96.                             this.hideItem(c);
  97.                         }
  98.                     }else{
  99.                         if(c.xtbHidden){
  100.                             this.unhideItem(c);
  101.                         }
  102.                     }
  103.                 }
  104.             }
  105.         }
  106.         if(this.hiddens){
  107.             this.initMore();
  108.             if(!this.lastOverflow){
  109.                 this.container.fireEvent('overflowchange', this.container, true);
  110.                 this.lastOverflow = true;
  111.             }
  112.         }else if(this.more){
  113.             this.clearMenu();
  114.             this.more.destroy();
  115.             delete this.more;
  116.             if(this.lastOverflow){
  117.                 this.container.fireEvent('overflowchange', this.container, false);
  118.                 this.lastOverflow = false;
  119.             }
  120.         }
  121.     },
  122.     createMenuConfig : function(c, hideOnClick){
  123.         var cfg = Ext.apply({}, c.initialConfig),
  124.             group = c.toggleGroup;
  125.         Ext.apply(cfg, {
  126.             text: c.overflowText || c.text,
  127.             iconCls: c.iconCls,
  128.             icon: c.icon,
  129.             itemId: c.itemId,
  130.             disabled: c.disabled,
  131.             handler: c.handler,
  132.             scope: c.scope,
  133.             menu: c.menu,
  134.             hideOnClick: hideOnClick
  135.         });
  136.         if(group || c.enableToggle){
  137.             Ext.apply(cfg, {
  138.                 group: group,
  139.                 checked: c.pressed,
  140.                 listeners: {
  141.                     checkchange: function(item, checked){
  142.                         c.toggle(checked);
  143.                     }
  144.                 }
  145.             });
  146.         }
  147.         delete cfg.xtype;
  148.         delete cfg.id;
  149.         return cfg;
  150.     },
  151.     // private
  152.     addComponentToMenu : function(m, c){
  153.         if(c instanceof Ext.Toolbar.Separator){
  154.             m.add('-');
  155.         }else if(Ext.isFunction(c.isXType)){
  156.             if(c.isXType('splitbutton')){
  157.                 m.add(this.createMenuConfig(c, true));
  158.             }else if(c.isXType('button')){
  159.                 m.add(this.createMenuConfig(c, !c.menu));
  160.             }else if(c.isXType('buttongroup')){
  161.                 c.items.each(function(item){
  162.                      this.addComponentToMenu(m, item);
  163.                 }, this);
  164.             }
  165.         }
  166.     },
  167.     clearMenu : function(){
  168.         var m = this.moreMenu;
  169.         if(m && m.items){
  170.             this.moreMenu.items.each(function(item){
  171.                 delete item.menu;
  172.             });
  173.         }
  174.     },
  175.     // private
  176.     beforeMoreShow : function(m){
  177.         var h = this.container.items.items,
  178.             len = h.length,
  179.             c,
  180.             prev,
  181.             needsSep = function(group, item){
  182.                 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
  183.             };
  184.         this.clearMenu();
  185.         m.removeAll();
  186.         for(var i = 0; i < len; i++){
  187.             c = h[i];
  188.             if(c.xtbHidden){
  189.                 if(prev && (needsSep(c, prev) || needsSep(prev, c))){
  190.                     m.add('-');
  191.                 }
  192.                 this.addComponentToMenu(m, c);
  193.                 prev = c;
  194.             }
  195.         }
  196.         // put something so the menu isn't empty
  197.         // if no compatible items found
  198.         if(m.items.length < 1){
  199.             m.add(this.noItemsMenuText);
  200.         }
  201.     },
  202.     initMore : function(){
  203.         if(!this.more){
  204.             this.moreMenu = new Ext.menu.Menu({
  205.                 listeners: {
  206.                     beforeshow: this.beforeMoreShow,
  207.                     scope: this
  208.                 }
  209.             });
  210.             this.more = new Ext.Button({
  211.                 iconCls: 'x-toolbar-more-icon',
  212.                 cls: 'x-toolbar-more',
  213.                 menu: this.moreMenu
  214.             });
  215.             var td = this.insertCell(this.more, this.extrasTr, 100);
  216.             this.more.render(td);
  217.         }
  218.     },
  219.     destroy : function(){
  220.         Ext.destroy(this.more, this.moreMenu);
  221.         Ext.layout.ToolbarLayout.superclass.destroy.call(this);
  222.     }
  223.     /**
  224.      * @property activeItem
  225.      * @hide
  226.      */
  227. });
  228. Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
  229. /**
  230.  * @class Ext.Toolbar
  231.  * @extends Ext.Container
  232.  * <p>Basic Toolbar class. Although the <tt>{@link Ext.Container#defaultType defaultType}</tt> for Toolbar
  233.  * is <tt>{@link Ext.Button button}</tt>, Toolbar elements (child items for the Toolbar container) may
  234.  * be virtually any type of Component. Toolbar elements can be created explicitly via their constructors,
  235.  * or implicitly via their xtypes, and can be <tt>{@link #add}</tt>ed dynamically.</p>
  236.  * <p>Some items have shortcut strings for creation:</p>
  237.  * <pre>
  238. <u>Shortcut</u>  <u>xtype</u>          <u>Class</u>                  <u>Description</u>
  239. '->'      'tbfill'       {@link Ext.Toolbar.Fill}       begin using the right-justified button container
  240. '-'       'tbseparator'  {@link Ext.Toolbar.Separator}  add a vertical separator bar between toolbar items
  241. ' '       'tbspacer'     {@link Ext.Toolbar.Spacer}     add horiztonal space between elements
  242.  * </pre>
  243.  *
  244.  * Example usage of various elements:
  245.  * <pre><code>
  246. var tb = new Ext.Toolbar({
  247.     renderTo: document.body,
  248.     width: 600,
  249.     height: 100,
  250.     items: [
  251.         {
  252.             // xtype: 'button', // default for Toolbars, same as 'tbbutton'
  253.             text: 'Button'
  254.         },
  255.         {
  256.             xtype: 'splitbutton', // same as 'tbsplitbutton'
  257.             text: 'Split Button'
  258.         },
  259.         // begin using the right-justified button container
  260.         '->', // same as {xtype: 'tbfill'}, // Ext.Toolbar.Fill
  261.         {
  262.             xtype: 'textfield',
  263.             name: 'field1',
  264.             emptyText: 'enter search term'
  265.         },
  266.         // add a vertical separator bar between toolbar items
  267.         '-', // same as {xtype: 'tbseparator'} to create Ext.Toolbar.Separator
  268.         'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.Toolbar.TextItem
  269.         {xtype: 'tbspacer'},// same as ' ' to create Ext.Toolbar.Spacer
  270.         'text 2',
  271.         {xtype: 'tbspacer', width: 50}, // add a 50px space
  272.         'text 3'
  273.     ]
  274. });
  275.  * </code></pre>
  276.  * Example adding a ComboBox within a menu of a button:
  277.  * <pre><code>
  278. // ComboBox creation
  279. var combo = new Ext.form.ComboBox({
  280.     store: new Ext.data.ArrayStore({
  281.         autoDestroy: true,
  282.         fields: ['initials', 'fullname'],
  283.         data : [
  284.             ['FF', 'Fred Flintstone'],
  285.             ['BR', 'Barney Rubble']
  286.         ]
  287.     }),
  288.     displayField: 'fullname',
  289.     typeAhead: true,
  290.     mode: 'local',
  291.     forceSelection: true,
  292.     triggerAction: 'all',
  293.     emptyText: 'Select a name...',
  294.     selectOnFocus: true,
  295.     width: 135,
  296.     getListParent: function() {
  297.         return this.el.up('.x-menu');
  298.     },
  299.     iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu
  300. });
  301. // put ComboBox in a Menu
  302. var menu = new Ext.menu.Menu({
  303.     id: 'mainMenu',
  304.     items: [
  305.         combo // A Field in a Menu
  306.     ]
  307. });
  308. // add a Button with the menu
  309. tb.add({
  310.         text:'Button w/ Menu',
  311.         menu: menu  // assign menu by instance
  312.     });
  313. tb.doLayout();
  314.  * </code></pre>
  315.  * @constructor
  316.  * Creates a new Toolbar
  317.  * @param {Object/Array} config A config object or an array of buttons to <tt>{@link #add}</tt>
  318.  * @xtype toolbar
  319.  */
  320. Ext.Toolbar = function(config){
  321.     if(Ext.isArray(config)){
  322.         config = {items: config, layout: 'toolbar'};
  323.     } else {
  324.         config = Ext.apply({
  325.             layout: 'toolbar'
  326.         }, config);
  327.         if(config.buttons) {
  328.             config.items = config.buttons;
  329.         }
  330.     }
  331.     Ext.Toolbar.superclass.constructor.call(this, config);
  332. };
  333. (function(){
  334. var T = Ext.Toolbar;
  335. Ext.extend(T, Ext.Container, {
  336.     defaultType: 'button',
  337.     trackMenus : true,
  338.     internalDefaults: {removeMode: 'container', hideParent: true},
  339.     toolbarCls: 'x-toolbar',
  340.     initComponent : function(){
  341.         T.superclass.initComponent.call(this);
  342.         /**
  343.          * @event overflowchange
  344.          * Fires after the overflow state has changed.
  345.          * @param {Object} c The Container
  346.          * @param {Boolean} lastOverflow overflow state
  347.          */
  348.         this.addEvents('overflowchange');
  349.     },
  350.     // private
  351.     onRender : function(ct, position){
  352.         if(!this.el){
  353.             if(!this.autoCreate){
  354.                 this.autoCreate = {
  355.                     cls: this.toolbarCls + ' x-small-editor'
  356.                 };
  357.             }
  358.             this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
  359.         }
  360.     },
  361.     /**
  362.      * Adds element(s) to the toolbar -- this function takes a variable number of
  363.      * arguments of mixed type and adds them to the toolbar.
  364.      * @param {Mixed} arg1 The following types of arguments are all valid:<br />
  365.      * <ul>
  366.      * <li>{@link Ext.Button} config: A valid button config object (equivalent to {@link #addButton})</li>
  367.      * <li>HtmlElement: Any standard HTML element (equivalent to {@link #addElement})</li>
  368.      * <li>Field: Any form field (equivalent to {@link #addField})</li>
  369.      * <li>Item: Any subclass of {@link Ext.Toolbar.Item} (equivalent to {@link #addItem})</li>
  370.      * <li>String: Any generic string (gets wrapped in a {@link Ext.Toolbar.TextItem}, equivalent to {@link #addText}).
  371.      * Note that there are a few special strings that are treated differently as explained next.</li>
  372.      * <li>'-': Creates a separator element (equivalent to {@link #addSeparator})</li>
  373.      * <li>' ': Creates a spacer element (equivalent to {@link #addSpacer})</li>
  374.      * <li>'->': Creates a fill element (equivalent to {@link #addFill})</li>
  375.      * </ul>
  376.      * @param {Mixed} arg2
  377.      * @param {Mixed} etc.
  378.      * @method add
  379.      */
  380.     // private
  381.     lookupComponent : function(c){
  382.         if(Ext.isString(c)){
  383.             if(c == '-'){
  384.                 c = new T.Separator();
  385.             }else if(c == ' '){
  386.                 c = new T.Spacer();
  387.             }else if(c == '->'){
  388.                 c = new T.Fill();
  389.             }else{
  390.                 c = new T.TextItem(c);
  391.             }
  392.             this.applyDefaults(c);
  393.         }else{
  394.             if(c.isFormField || c.render){ // some kind of form field, some kind of Toolbar.Item
  395.                 c = this.constructItem(c);
  396.             }else if(c.tag){ // DomHelper spec
  397.                 c = new T.Item({autoEl: c});
  398.             }else if(c.tagName){ // element
  399.                 c = new T.Item({el:c});
  400.             }else if(Ext.isObject(c)){ // must be button config?
  401.                 c = c.xtype ? this.constructItem(c) : this.constructButton(c);
  402.             }
  403.         }
  404.         return c;
  405.     },
  406.     // private
  407.     applyDefaults : function(c){
  408.         if(!Ext.isString(c)){
  409.             c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
  410.             var d = this.internalDefaults;
  411.             if(c.events){
  412.                 Ext.applyIf(c.initialConfig, d);
  413.                 Ext.apply(c, d);
  414.             }else{
  415.                 Ext.applyIf(c, d);
  416.             }
  417.         }
  418.         return c;
  419.     },
  420.     // private
  421.     constructItem : function(item, type){
  422.         return Ext.create(item, type || this.defaultType);
  423.     },
  424.     /**
  425.      * Adds a separator
  426.      * @return {Ext.Toolbar.Item} The separator {@link Ext.Toolbar.Item item}
  427.      */
  428.     addSeparator : function(){
  429.         return this.add(new T.Separator());
  430.     },
  431.     /**
  432.      * Adds a spacer element
  433.      * @return {Ext.Toolbar.Spacer} The spacer item
  434.      */
  435.     addSpacer : function(){
  436.         return this.add(new T.Spacer());
  437.     },
  438.     /**
  439.      * Forces subsequent additions into the float:right toolbar
  440.      */
  441.     addFill : function(){
  442.         this.add(new T.Fill());
  443.     },
  444.     /**
  445.      * Adds any standard HTML element to the toolbar
  446.      * @param {Mixed} el The element or id of the element to add
  447.      * @return {Ext.Toolbar.Item} The element's item
  448.      */
  449.     addElement : function(el){
  450.         return this.addItem(new T.Item({el:el}));
  451.     },
  452.     /**
  453.      * Adds any Toolbar.Item or subclass
  454.      * @param {Ext.Toolbar.Item} item
  455.      * @return {Ext.Toolbar.Item} The item
  456.      */
  457.     addItem : function(item){
  458.         return Ext.Toolbar.superclass.add.apply(this, arguments);
  459.     },
  460.     /**
  461.      * Adds a button (or buttons). See {@link Ext.Button} for more info on the config.
  462.      * @param {Object/Array} config A button config or array of configs
  463.      * @return {Ext.Button/Array}
  464.      */
  465.     addButton : function(config){
  466.         if(Ext.isArray(config)){
  467.             var buttons = [];
  468.             for(var i = 0, len = config.length; i < len; i++) {
  469.                 buttons.push(this.addButton(config[i]));
  470.             }
  471.             return buttons;
  472.         }
  473.         return this.add(this.constructButton(config));
  474.     },
  475.     /**
  476.      * Adds text to the toolbar
  477.      * @param {String} text The text to add
  478.      * @return {Ext.Toolbar.Item} The element's item
  479.      */
  480.     addText : function(text){
  481.         return this.addItem(new T.TextItem(text));
  482.     },
  483.     /**
  484.      * Adds a new element to the toolbar from the passed {@link Ext.DomHelper} config
  485.      * @param {Object} config
  486.      * @return {Ext.Toolbar.Item} The element's item
  487.      */
  488.     addDom : function(config){
  489.         return this.add(new T.Item({autoEl: config}));
  490.     },
  491.     /**
  492.      * Adds a dynamically rendered Ext.form field (TextField, ComboBox, etc). Note: the field should not have
  493.      * been rendered yet. For a field that has already been rendered, use {@link #addElement}.
  494.      * @param {Ext.form.Field} field
  495.      * @return {Ext.Toolbar.Item}
  496.      */
  497.     addField : function(field){
  498.         return this.add(field);
  499.     },
  500.     /**
  501.      * Inserts any {@link Ext.Toolbar.Item}/{@link Ext.Button} at the specified index.
  502.      * @param {Number} index The index where the item is to be inserted
  503.      * @param {Object/Ext.Toolbar.Item/Ext.Button/Array} item The button, or button config object to be
  504.      * inserted, or an array of buttons/configs.
  505.      * @return {Ext.Button/Item}
  506.      */
  507.     insertButton : function(index, item){
  508.         if(Ext.isArray(item)){
  509.             var buttons = [];
  510.             for(var i = 0, len = item.length; i < len; i++) {
  511.                buttons.push(this.insertButton(index + i, item[i]));
  512.             }
  513.             return buttons;
  514.         }
  515.         return Ext.Toolbar.superclass.insert.call(this, index, item);
  516.     },
  517.     // private
  518.     initMenuTracking : function(item){
  519.         if(this.trackMenus && item.menu){
  520.             this.mon(item, {
  521.                 'menutriggerover' : this.onButtonTriggerOver,
  522.                 'menushow' : this.onButtonMenuShow,
  523.                 'menuhide' : this.onButtonMenuHide,
  524.                 scope: this
  525.             });
  526.         }
  527.     },
  528.     // private
  529.     constructButton : function(item){
  530.         var b = item.events ? item : this.constructItem(item, item.split ? 'splitbutton' : this.defaultType);
  531.         this.initMenuTracking(b);
  532.         return b;
  533.     },
  534.     // private
  535.     onDisable : function(){
  536.         this.items.each(function(item){
  537.              if(item.disable){
  538.                  item.disable();
  539.              }
  540.         });
  541.     },
  542.     // private
  543.     onEnable : function(){
  544.         this.items.each(function(item){
  545.              if(item.enable){
  546.                  item.enable();
  547.              }
  548.         });
  549.     },
  550.     // private
  551.     onButtonTriggerOver : function(btn){
  552.         if(this.activeMenuBtn && this.activeMenuBtn != btn){
  553.             this.activeMenuBtn.hideMenu();
  554.             btn.showMenu();
  555.             this.activeMenuBtn = btn;
  556.         }
  557.     },
  558.     // private
  559.     onButtonMenuShow : function(btn){
  560.         this.activeMenuBtn = btn;
  561.     },
  562.     // private
  563.     onButtonMenuHide : function(btn){
  564.         delete this.activeMenuBtn;
  565.     }
  566. });
  567. Ext.reg('toolbar', Ext.Toolbar);
  568. /**
  569.  * @class Ext.Toolbar.Item
  570.  * @extends Ext.BoxComponent
  571.  * The base class that other non-interacting Toolbar Item classes should extend in order to
  572.  * get some basic common toolbar item functionality.
  573.  * @constructor
  574.  * Creates a new Item
  575.  * @param {HTMLElement} el
  576.  * @xtype tbitem
  577.  */
  578. T.Item = Ext.extend(Ext.BoxComponent, {
  579.     hideParent: true, //  Hiding a Toolbar.Item hides its containing TD
  580.     enable:Ext.emptyFn,
  581.     disable:Ext.emptyFn,
  582.     focus:Ext.emptyFn
  583.     /**
  584.      * @cfg {String} overflowText Text to be used for the menu if the item is overflowed.
  585.      */
  586. });
  587. Ext.reg('tbitem', T.Item);
  588. /**
  589.  * @class Ext.Toolbar.Separator
  590.  * @extends Ext.Toolbar.Item
  591.  * A simple class that adds a vertical separator bar between toolbar items
  592.  * (css class:<tt>'xtb-sep'</tt>). Example usage:
  593.  * <pre><code>
  594. new Ext.Panel({
  595.     tbar : [
  596.         'Item 1',
  597.         {xtype: 'tbseparator'}, // or '-'
  598.         'Item 2'
  599.     ]
  600. });
  601. </code></pre>
  602.  * @constructor
  603.  * Creates a new Separator
  604.  * @xtype tbseparator
  605.  */
  606. T.Separator = Ext.extend(T.Item, {
  607.     onRender : function(ct, position){
  608.         this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
  609.     }
  610. });
  611. Ext.reg('tbseparator', T.Separator);
  612. /**
  613.  * @class Ext.Toolbar.Spacer
  614.  * @extends Ext.Toolbar.Item
  615.  * A simple element that adds extra horizontal space between items in a toolbar.
  616.  * By default a 2px wide space is added via css specification:<pre><code>
  617. .x-toolbar .xtb-spacer {
  618.     width:2px;
  619. }
  620.  * </code></pre>
  621.  * <p>Example usage:</p>
  622.  * <pre><code>
  623. new Ext.Panel({
  624.     tbar : [
  625.         'Item 1',
  626.         {xtype: 'tbspacer'}, // or ' '
  627.         'Item 2',
  628.         // space width is also configurable via javascript
  629.         {xtype: 'tbspacer', width: 50}, // add a 50px space
  630.         'Item 3'
  631.     ]
  632. });
  633. </code></pre>
  634.  * @constructor
  635.  * Creates a new Spacer
  636.  * @xtype tbspacer
  637.  */
  638. T.Spacer = Ext.extend(T.Item, {
  639.     /**
  640.      * @cfg {Number} width
  641.      * The width of the spacer in pixels (defaults to 2px via css style <tt>.x-toolbar .xtb-spacer</tt>).
  642.      */
  643.     onRender : function(ct, position){
  644.         this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
  645.     }
  646. });
  647. Ext.reg('tbspacer', T.Spacer);
  648. /**
  649.  * @class Ext.Toolbar.Fill
  650.  * @extends Ext.Toolbar.Spacer
  651.  * A non-rendering placeholder item which instructs the Toolbar's Layout to begin using
  652.  * the right-justified button container.
  653.  * <pre><code>
  654. new Ext.Panel({
  655.     tbar : [
  656.         'Item 1',
  657.         {xtype: 'tbfill'}, // or '->'
  658.         'Item 2'
  659.     ]
  660. });
  661. </code></pre>
  662.  * @constructor
  663.  * Creates a new Fill
  664.  * @xtype tbfill
  665.  */
  666. T.Fill = Ext.extend(T.Item, {
  667.     // private
  668.     render : Ext.emptyFn,
  669.     isFill : true
  670. });
  671. Ext.reg('tbfill', T.Fill);
  672. /**
  673.  * @class Ext.Toolbar.TextItem
  674.  * @extends Ext.Toolbar.Item
  675.  * A simple class that renders text directly into a toolbar
  676.  * (with css class:<tt>'xtb-text'</tt>). Example usage:
  677.  * <pre><code>
  678. new Ext.Panel({
  679.     tbar : [
  680.         {xtype: 'tbtext', text: 'Item 1'} // or simply 'Item 1'
  681.     ]
  682. });
  683. </code></pre>
  684.  * @constructor
  685.  * Creates a new TextItem
  686.  * @param {String/Object} text A text string, or a config object containing a <tt>text</tt> property
  687.  * @xtype tbtext
  688.  */
  689. T.TextItem = Ext.extend(T.Item, {
  690.     constructor: function(config){
  691.         if (Ext.isString(config)) {
  692.             config = { autoEl: {cls: 'xtb-text', html: config }};
  693.         } else {
  694.             config.autoEl = {cls: 'xtb-text', html: config.text || ''};
  695.         }
  696.         T.TextItem.superclass.constructor.call(this, config);
  697.     },
  698.     /**
  699.      * Updates this item's text, setting the text to be used as innerHTML.
  700.      * @param {String} t The text to display (html accepted).
  701.      */
  702.     setText : function(t) {
  703.         if (this.rendered) {
  704.             this.el.dom.innerHTML = t;
  705.         } else {
  706.             this.autoEl.html = t;
  707.         }
  708.     }
  709. });
  710. Ext.reg('tbtext', T.TextItem);
  711. // backwards compat
  712. T.Button = Ext.extend(Ext.Button, {});
  713. T.SplitButton = Ext.extend(Ext.SplitButton, {});
  714. Ext.reg('tbbutton', T.Button);
  715. Ext.reg('tbsplit', T.SplitButton);
  716. })();
  717. /**
  718.  * @class Ext.ButtonGroup
  719.  * @extends Ext.Panel
  720.  * Container for a group of buttons. Example usage:
  721.  * <pre><code>
  722. var p = new Ext.Panel({
  723.     title: 'Panel with Button Group',
  724.     width: 300,
  725.     height:200,
  726.     renderTo: document.body,
  727.     html: 'whatever',
  728.     tbar: [{
  729.         xtype: 'buttongroup',
  730.         {@link #columns}: 3,
  731.         title: 'Clipboard',
  732.         items: [{
  733.             text: 'Paste',
  734.             scale: 'large',
  735.             rowspan: 3, iconCls: 'add',
  736.             iconAlign: 'top',
  737.             cls: 'x-btn-as-arrow'
  738.         },{
  739.             xtype:'splitbutton',
  740.             text: 'Menu Button',
  741.             scale: 'large',
  742.             rowspan: 3,
  743.             iconCls: 'add',
  744.             iconAlign: 'top',
  745.             arrowAlign:'bottom',
  746.             menu: [{text: 'Menu Item 1'}]
  747.         },{
  748.             xtype:'splitbutton', text: 'Cut', iconCls: 'add16', menu: [{text: 'Cut Menu Item'}]
  749.         },{
  750.             text: 'Copy', iconCls: 'add16'
  751.         },{
  752.             text: 'Format', iconCls: 'add16'
  753.         }]
  754.     }]
  755. });
  756.  * </code></pre>
  757.  * @xtype buttongroup
  758.  */
  759. Ext.ButtonGroup = Ext.extend(Ext.Panel, {
  760.     /**
  761.      * @cfg {Number} columns The <tt>columns</tt> configuration property passed to the
  762.      * {@link #layout configured layout manager}. See {@link Ext.layout.TableLayout#columns}.
  763.      */
  764.     /**
  765.      * @cfg {String} baseCls  Defaults to <tt>'x-btn-group'</tt>.  See {@link Ext.Panel#baseCls}.
  766.      */
  767.     baseCls: 'x-btn-group',
  768.     /**
  769.      * @cfg {String} layout  Defaults to <tt>'table'</tt>.  See {@link Ext.Container#layout}.
  770.      */
  771.     layout:'table',
  772.     defaultType: 'button',
  773.     /**
  774.      * @cfg {Boolean} frame  Defaults to <tt>true</tt>.  See {@link Ext.Panel#frame}.
  775.      */
  776.     frame: true,
  777.     internalDefaults: {removeMode: 'container', hideParent: true},
  778.     initComponent : function(){
  779.         this.layoutConfig = this.layoutConfig || {};
  780.         Ext.applyIf(this.layoutConfig, {
  781.             columns : this.columns
  782.         });
  783.         if(!this.title){
  784.             this.addClass('x-btn-group-notitle');
  785.         }
  786.         this.on('afterlayout', this.onAfterLayout, this);
  787.         Ext.ButtonGroup.superclass.initComponent.call(this);
  788.     },
  789.     applyDefaults : function(c){
  790.         c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
  791.         var d = this.internalDefaults;
  792.         if(c.events){
  793.             Ext.applyIf(c.initialConfig, d);
  794.             Ext.apply(c, d);
  795.         }else{
  796.             Ext.applyIf(c, d);
  797.         }
  798.         return c;
  799.     },
  800.     onAfterLayout : function(){
  801.         var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
  802.         this.body.setWidth(bodyWidth);
  803.         this.el.setWidth(bodyWidth + this.getFrameWidth());
  804.     }
  805.     /**
  806.      * @cfg {Array} tools  @hide
  807.      */
  808. });
  809. Ext.reg('buttongroup', Ext.ButtonGroup);
  810. /**  * @class Ext.PagingToolbar  * @extends Ext.Toolbar  * <p>As the amount of records increases, the time required for the browser to render  * them increases. Paging is used to reduce the amount of data exchanged with the client.  * Note: if there are more records/rows than can be viewed in the available screen area, vertical  * scrollbars will be added.</p>  * <p>Paging is typically handled on the server side (see exception below). The client sends  * parameters to the server side, which the server needs to interpret and then respond with the  * approprate data.</p>  * <p><b>Ext.PagingToolbar</b> is a specialized toolbar that is bound to a {@link Ext.data.Store}  * and provides automatic paging control. This Component {@link Ext.data.Store#load load}s blocks  * of data into the <tt>{@link #store}</tt> by passing {@link Ext.data.Store#paramNames paramNames} used for  * paging criteria.</p>  * <p>PagingToolbar is typically used as one of the Grid's toolbars:</p>  * <pre><code> Ext.QuickTips.init(); // to display button quicktips var myStore = new Ext.data.Store({     ... }); var myPageSize = 25;  // server script should only send back 25 items var grid = new Ext.grid.GridPanel({     ...     store: myStore,     bbar: new Ext.PagingToolbar({         {@link #store}: myStore,       // grid and PagingToolbar using same store         {@link #displayInfo}: true,         {@link #pageSize}: myPageSize,         {@link #prependButtons}: true,         items: [             'text 1'         ]     }) });  * </code></pre>  *  * <p>To use paging, pass the paging requirements to the server when the store is first loaded.</p>  * <pre><code> store.load({     params: {         start: 0,          // specify params for the first page load if using paging         limit: myPageSize,         foo:   'bar'     } });  * </code></pre>  * <p><u>Paging with Local Data</u></p>  * <p>Paging can also be accomplished with local data using extensions:</p>  * <div class="mdetail-params"><ul>  * <li><a href="http://extjs.com/forum/showthread.php?t=57386">Ext.ux.data.PagingStore</a></li>  * <li>Paging Memory Proxy (examples/ux/PagingMemoryProxy.js)</li>  * </ul></div>  * @constructor  * Create a new PagingToolbar  * @param {Object} config The config object  * @xtype paging  */ (function() { var T = Ext.Toolbar; Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {     /**      * @cfg {Ext.data.Store} store      * The {@link Ext.data.Store} the paging toolbar should use as its data source (required).      */     /**      * @cfg {Boolean} displayInfo      * <tt>true</tt> to display the displayMsg (defaults to <tt>false</tt>)      */     /**      * @cfg {Number} pageSize      * The number of records to display per page (defaults to <tt>20</tt>)      */     pageSize : 20,     /**      * @cfg {Boolean} prependButtons      * <tt>true</tt> to insert any configured <tt>items</tt> <i>before</i> the paging buttons.      * Defaults to <tt>false</tt>.      */     /**      * @cfg {String} displayMsg      * The paging status message to display (defaults to <tt>'Displaying {0} - {1} of {2}'</tt>).      * Note that this string is formatted using the braced numbers <tt>{0}-{2}</tt> as tokens      * that are replaced by the values for start, end and total respectively. These tokens should      * be preserved when overriding this string if showing those values is desired.      */     displayMsg : 'Displaying {0} - {1} of {2}',     /**      * @cfg {String} emptyMsg      * The message to display when no records are found (defaults to 'No data to display')      */     emptyMsg : 'No data to display',     /**      * @cfg {String} beforePageText      * The text displayed before the input item (defaults to <tt>'Page'</tt>).      */     beforePageText : 'Page',     /**      * @cfg {String} afterPageText      * Customizable piece of the default paging text (defaults to <tt>'of {0}'</tt>). Note that      * this string is formatted using <tt>{0}</tt> as a token that is replaced by the number of      * total pages. This token should be preserved when overriding this string if showing the      * total page count is desired.      */     afterPageText : 'of {0}',     /**      * @cfg {String} firstText      * The quicktip text displayed for the first page button (defaults to <tt>'First Page'</tt>).      * <b>Note</b>: quick tips must be initialized for the quicktip to show.      */     firstText : 'First Page',     /**      * @cfg {String} prevText      * The quicktip text displayed for the previous page button (defaults to <tt>'Previous Page'</tt>).      * <b>Note</b>: quick tips must be initialized for the quicktip to show.      */     prevText : 'Previous Page',     /**      * @cfg {String} nextText      * The quicktip text displayed for the next page button (defaults to <tt>'Next Page'</tt>).      * <b>Note</b>: quick tips must be initialized for the quicktip to show.      */     nextText : 'Next Page',     /**      * @cfg {String} lastText      * The quicktip text displayed for the last page button (defaults to <tt>'Last Page'</tt>).      * <b>Note</b>: quick tips must be initialized for the quicktip to show.      */     lastText : 'Last Page',     /**      * @cfg {String} refreshText      * The quicktip text displayed for the Refresh button (defaults to <tt>'Refresh'</tt>).      * <b>Note</b>: quick tips must be initialized for the quicktip to show.      */     refreshText : 'Refresh',     /**      * @deprecated      * <b>The defaults for these should be set in the data store.</b>      * Object mapping of parameter names used for load calls, initially set to:      * <pre>{start: 'start', limit: 'limit'}</pre>      */     /**      * The number of records to display per page.  See also <tt>{@link #cursor}</tt>.      * @type Number      * @property pageSize      */     /**      * Indicator for the record position.  This property might be used to get the active page      * number for example:<pre><code>      * // t is reference to the paging toolbar instance      * var activePage = Math.ceil((t.cursor + t.pageSize) / t.pageSize);      * </code></pre>      * @type Number      * @property cursor      */     initComponent : function(){         var pagingItems = [this.first = new T.Button({             tooltip: this.firstText,             overflowText: this.firstText,             iconCls: 'x-tbar-page-first',             disabled: true,             handler: this.moveFirst,             scope: this         }), this.prev = new T.Button({             tooltip: this.prevText,             overflowText: this.prevText,             iconCls: 'x-tbar-page-prev',             disabled: true,             handler: this.movePrevious,             scope: this         }), '-', this.beforePageText,         this.inputItem = new Ext.form.NumberField({             cls: 'x-tbar-page-number',             allowDecimals: false,             allowNegative: false,             enableKeyEvents: true,             selectOnFocus: true,             listeners: {                 scope: this,                 keydown: this.onPagingKeyDown,                 blur: this.onPagingBlur             }         }), this.afterTextItem = new T.TextItem({             text: String.format(this.afterPageText, 1)         }), '-', this.next = new T.Button({             tooltip: this.nextText,             overflowText: this.nextText,             iconCls: 'x-tbar-page-next',             disabled: true,             handler: this.moveNext,             scope: this         }), this.last = new T.Button({             tooltip: this.lastText,             overflowText: this.lastText,             iconCls: 'x-tbar-page-last',             disabled: true,             handler: this.moveLast,             scope: this         }), '-', this.refresh = new T.Button({             tooltip: this.refreshText,             overflowText: this.refreshText,             iconCls: 'x-tbar-loading',             handler: this.refresh,             scope: this         })];         var userItems = this.items || this.buttons || [];         if (this.prependButtons) {             this.items = userItems.concat(pagingItems);         }else{             this.items = pagingItems.concat(userItems);         }         delete this.buttons;         if(this.displayInfo){             this.items.push('->');             this.items.push(this.displayItem = new T.TextItem({}));         }         Ext.PagingToolbar.superclass.initComponent.call(this);         this.addEvents(             /**              * @event change              * Fires after the active page has been changed.              * @param {Ext.PagingToolbar} this              * @param {Object} pageData An object that has these properties:<ul>              * <li><code>total</code> : Number <div class="sub-desc">The total number of records in the dataset as              * returned by the server</div></li>              * <li><code>activePage</code> : Number <div class="sub-desc">The current page number</div></li>              * <li><code>pages</code> : Number <div class="sub-desc">The total number of pages (calculated from              * the total number of records in the dataset as returned by the server and the current {@link #pageSize})</div></li>              * </ul>              */             'change',             /**              * @event beforechange              * Fires just before the active page is changed.              * Return false to prevent the active page from being changed.              * @param {Ext.PagingToolbar} this              * @param {Object} params An object hash of the parameters which the PagingToolbar will send when              * loading the required page. This will contain:<ul>              * <li><code>start</code> : Number <div class="sub-desc">The starting row number for the next page of records to              * be retrieved from the server</div></li>              * <li><code>limit</code> : Number <div class="sub-desc">The number of records to be retrieved from the server</div></li>              * </ul>              * <p>(note: the names of the <b>start</b> and <b>limit</b> properties are determined              * by the store's {@link Ext.data.Store#paramNames paramNames} property.)</p>              * <p>Parameters may be added as required in the event handler.</p>              */             'beforechange'         );         this.on('afterlayout', this.onFirstLayout, this, {single: true});         this.cursor = 0;         this.bindStore(this.store);     },     // private     onFirstLayout : function(){         if(this.dsLoaded){             this.onLoad.apply(this, this.dsLoaded);         }     },     // private     updateInfo : function(){         if(this.displayItem){             var count = this.store.getCount();             var msg = count == 0 ?                 this.emptyMsg :                 String.format(                     this.displayMsg,                     this.cursor+1, this.cursor+count, this.store.getTotalCount()                 );             this.displayItem.setText(msg);         }     },     // private     onLoad : function(store, r, o){         if(!this.rendered){             this.dsLoaded = [store, r, o];             return;         }         var p = this.getParams();         this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;         var d = this.getPageData(), ap = d.activePage, ps = d.pages;         this.afterTextItem.setText(String.format(this.afterPageText, d.pages));         this.inputItem.setValue(ap);         this.first.setDisabled(ap == 1);         this.prev.setDisabled(ap == 1);         this.next.setDisabled(ap == ps);         this.last.setDisabled(ap == ps);         this.refresh.enable();         this.updateInfo();         this.fireEvent('change', this, d);     },     // private     getPageData : function(){         var total = this.store.getTotalCount();         return {             total : total,             activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),             pages :  total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)         };     },     /**      * Change the active page      * @param {Integer} page The page to display      */     changePage : function(page){         this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));     },     // private     onLoadError : function(){         if(!this.rendered){             return;         }         this.refresh.enable();     },     // private     readPage : function(d){         var v = this.inputItem.getValue(), pageNum;         if (!v || isNaN(pageNum = parseInt(v, 10))) {             this.inputItem.setValue(d.activePage);             return false;         }         return pageNum;     },     onPagingFocus : function(){         this.inputItem.select();     },     //private     onPagingBlur : function(e){         this.inputItem.setValue(this.getPageData().activePage);     },     // private     onPagingKeyDown : function(field, e){         var k = e.getKey(), d = this.getPageData(), pageNum;         if (k == e.RETURN) {             e.stopEvent();             pageNum = this.readPage(d);             if(pageNum !== false){                 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;                 this.doLoad(pageNum * this.pageSize);             }         }else if (k == e.HOME || k == e.END){             e.stopEvent();             pageNum = k == e.HOME ? 1 : d.pages;             field.setValue(pageNum);         }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){             e.stopEvent();             if((pageNum = this.readPage(d))){                 var increment = e.shiftKey ? 10 : 1;                 if(k == e.DOWN || k == e.PAGEDOWN){                     increment *= -1;                 }                 pageNum += increment;                 if(pageNum >= 1 & pageNum <= d.pages){                     field.setValue(pageNum);                 }             }         }     },     // private     getParams : function(){         //retain backwards compat, allow params on the toolbar itself, if they exist.         return this.paramNames || this.store.paramNames;     },     // private     beforeLoad : function(){         if(this.rendered && this.refresh){             this.refresh.disable();         }     },     // private     doLoad : function(start){         var o = {}, pn = this.getParams();         o[pn.start] = start;         o[pn.limit] = this.pageSize;         if(this.fireEvent('beforechange', this, o) !== false){             this.store.load({params:o});         }     },     /**      * Move to the first page, has the same effect as clicking the 'first' button.      */     moveFirst : function(){         this.doLoad(0);     },     /**      * Move to the previous page, has the same effect as clicking the 'previous' button.      */     movePrevious : function(){         this.doLoad(Math.max(0, this.cursor-this.pageSize));     },     /**      * Move to the next page, has the same effect as clicking the 'next' button.      */     moveNext : function(){         this.doLoad(this.cursor+this.pageSize);     },     /**      * Move to the last page, has the same effect as clicking the 'last' button.      */     moveLast : function(){         var total = this.store.getTotalCount(),             extra = total % this.pageSize;         this.doLoad(extra ? (total - extra) : total - this.pageSize);     },     /**      * Refresh the current page, has the same effect as clicking the 'refresh' button.      */     refresh : function(){         this.doLoad(this.cursor);     },     /**      * Binds the paging toolbar to the specified {@link Ext.data.Store}      * @param {Store} store The store to bind to this toolbar      * @param {Boolean} initial (Optional) true to not remove listeners      */     bindStore : function(store, initial){         var doLoad;         if(!initial && this.store){             this.store.un('beforeload', this.beforeLoad, this);             this.store.un('load', this.onLoad, this);             this.store.un('exception', this.onLoadError, this);             if(store !== this.store && this.store.autoDestroy){                 this.store.destroy();             }         }         if(store){             store = Ext.StoreMgr.lookup(store);             store.on({                 scope: this,                 beforeload: this.beforeLoad,                 load: this.onLoad,                 exception: this.onLoadError             });             doLoad = store.getCount() > 0;         }         this.store = store;         if(doLoad){             this.onLoad(store, null, {});         }     },     /**      * Unbinds the paging toolbar from the specified {@link Ext.data.Store} <b>(deprecated)</b>      * @param {Ext.data.Store} store The data store to unbind      */     unbind : function(store){         this.bindStore(null);     },     /**      * Binds the paging toolbar to the specified {@link Ext.data.Store} <b>(deprecated)</b>      * @param {Ext.data.Store} store The data store to bind      */     bind : function(store){         this.bindStore(store);     },     // private     onDestroy : function(){         this.bindStore(null);         Ext.PagingToolbar.superclass.onDestroy.call(this);     } }); })(); Ext.reg('paging', Ext.PagingToolbar);