X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/ee06f37b0f6f6d94cd05a6ffae556660f7c4a2bc..c930e9176a5a85509c5b0230e2bff5c22a591432:/docs/source/Toolbar.html diff --git a/docs/source/Toolbar.html b/docs/source/Toolbar.html new file mode 100644 index 00000000..2ffa4cc7 --- /dev/null +++ b/docs/source/Toolbar.html @@ -0,0 +1,805 @@ + + + The source code + + + + +
/** + * @class Ext.layout.ToolbarLayout + * @extends Ext.layout.ContainerLayout + * Layout manager implicitly used by Ext.Toolbar. + */ +Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, { + monitorResize : true, + triggerWidth : 18, + lastOverflow : false, + + noItemsMenuText : '
(None)
', + // private + onLayout : function(ct, target){ + if(!this.leftTr){ + target.addClass('x-toolbar-layout-ct'); + target.insertHtml('beforeEnd', + '
'); + this.leftTr = target.child('tr.x-toolbar-left-row', true); + this.rightTr = target.child('tr.x-toolbar-right-row', true); + this.extrasTr = target.child('tr.x-toolbar-extras-row', true); + } + var side = this.leftTr; + var pos = 0; + + var items = ct.items.items; + for(var i = 0, len = items.length, c; i < len; i++, pos++) { + c = items[i]; + if(c.isFill){ + side = this.rightTr; + pos = -1; + }else if(!c.rendered){ + c.render(this.insertCell(c, side, pos)); + }else{ + if(!c.xtbHidden && !this.isValidParent(c, side.childNodes[pos])){ + var td = this.insertCell(c, side, pos); + td.appendChild(c.getDomPositionEl().dom); + c.container = Ext.get(td); + } + } + } + //strip extra empty cells + this.cleanup(this.leftTr); + this.cleanup(this.rightTr); + this.cleanup(this.extrasTr); + this.fitToSize(target); + }, + + cleanup : function(row){ + var cn = row.childNodes; + for(var i = cn.length-1, c; i >= 0 && (c = cn[i]); i--){ + if(!c.firstChild){ + row.removeChild(c); + } + } + }, + + insertCell : function(c, side, pos){ + var td = document.createElement('td'); + td.className='x-toolbar-cell'; + side.insertBefore(td, side.childNodes[pos]||null); + return td; + }, + + hideItem : function(item){ + var h = (this.hiddens = this.hiddens || []); + h.push(item); + item.xtbHidden = true; + item.xtbWidth = item.getDomPositionEl().dom.parentNode.offsetWidth; + item.hide(); + }, + + unhideItem : function(item){ + item.show(); + item.xtbHidden = false; + this.hiddens.remove(item); + if(this.hiddens.length < 1){ + delete this.hiddens; + } + }, + + getItemWidth : function(c){ + return c.hidden ? (c.xtbWidth || 0) : c.getDomPositionEl().dom.parentNode.offsetWidth; + }, + + fitToSize : function(t){ + if(this.container.enableOverflow === false){ + return; + } + var w = t.dom.clientWidth; + var lw = this.lastWidth || 0; + this.lastWidth = w; + var iw = t.dom.firstChild.offsetWidth; + + var clipWidth = w - this.triggerWidth; + var hideIndex = -1; + + if(iw > w || (this.hiddens && w >= lw)){ + var i, items = this.container.items.items, len = items.length, c; + var loopWidth = 0; + for(i = 0; i < len; i++) { + c = items[i]; + if(!c.isFill){ + loopWidth += this.getItemWidth(c); + if(loopWidth > clipWidth){ + if(!c.xtbHidden){ + this.hideItem(c); + } + }else{ + if(c.xtbHidden){ + this.unhideItem(c); + } + } + } + } + } + if(this.hiddens){ + this.initMore(); + if(!this.lastOverflow){ + this.container.fireEvent('overflowchange', this.container, true); + this.lastOverflow = true; + } + }else if(this.more){ + this.clearMenu(); + this.more.destroy(); + delete this.more; + if(this.lastOverflow){ + this.container.fireEvent('overflowchange', this.container, false); + this.lastOverflow = false; + } + } + }, + + createMenuConfig : function(c, hideOnClick){ + var cfg = Ext.apply({}, c.initialConfig), + group = c.toggleGroup; + + Ext.apply(cfg, { + text: c.overflowText || c.text, + iconCls: c.iconCls, + icon: c.icon, + itemId: c.itemId, + disabled: c.disabled, + handler: c.handler, + scope: c.scope, + menu: c.menu, + hideOnClick: hideOnClick + }); + if(group || c.enableToggle){ + Ext.apply(cfg, { + group: group, + checked: c.pressed, + listeners: { + checkchange: function(item, checked){ + c.toggle(checked); + } + } + }); + } + delete cfg.xtype; + delete cfg.id; + return cfg; + }, + + // private + addComponentToMenu : function(m, c){ + if(c instanceof Ext.Toolbar.Separator){ + m.add('-'); + }else if(Ext.isFunction(c.isXType)){ + if(c.isXType('splitbutton')){ + m.add(this.createMenuConfig(c, true)); + }else if(c.isXType('button')){ + m.add(this.createMenuConfig(c, !c.menu)); + }else if(c.isXType('buttongroup')){ + c.items.each(function(item){ + this.addComponentToMenu(m, item); + }, this); + } + } + }, + + clearMenu : function(){ + var m = this.moreMenu; + if(m && m.items){ + this.moreMenu.items.each(function(item){ + delete item.menu; + }); + } + }, + + // private + beforeMoreShow : function(m){ + var h = this.container.items.items, + len = h.length, + c, + prev, + needsSep = function(group, item){ + return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator); + }; + + this.clearMenu(); + m.removeAll(); + for(var i = 0; i < len; i++){ + c = h[i]; + if(c.xtbHidden){ + if(prev && (needsSep(c, prev) || needsSep(prev, c))){ + m.add('-'); + } + this.addComponentToMenu(m, c); + prev = c; + } + } + // put something so the menu isn't empty + // if no compatible items found + if(m.items.length < 1){ + m.add(this.noItemsMenuText); + } + }, + + initMore : function(){ + if(!this.more){ + this.moreMenu = new Ext.menu.Menu({ + listeners: { + beforeshow: this.beforeMoreShow, + scope: this + } + }); + this.more = new Ext.Button({ + iconCls: 'x-toolbar-more-icon', + cls: 'x-toolbar-more', + menu: this.moreMenu + }); + var td = this.insertCell(this.more, this.extrasTr, 100); + this.more.render(td); + } + }, + + destroy : function(){ + Ext.destroy(this.more, this.moreMenu); + Ext.layout.ToolbarLayout.superclass.destroy.call(this); + } +
/** + * @property activeItem + * @hide + */ +}); + +Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout; + +
/** + * @class Ext.Toolbar + * @extends Ext.Container + *

Basic Toolbar class. Although the {@link Ext.Container#defaultType defaultType} for Toolbar + * is {@link Ext.Button button}, Toolbar elements (child items for the Toolbar container) may + * be virtually any type of Component. Toolbar elements can be created explicitly via their constructors, + * or implicitly via their xtypes, and can be {@link #add}ed dynamically.

+ *

Some items have shortcut strings for creation:

+ *
+Shortcut  xtype          Class                  Description
+'->'      'tbfill'       {@link Ext.Toolbar.Fill}       begin using the right-justified button container
+'-'       'tbseparator'  {@link Ext.Toolbar.Separator}  add a vertical separator bar between toolbar items
+' '       'tbspacer'     {@link Ext.Toolbar.Spacer}     add horiztonal space between elements
+ * 
+ * + * Example usage of various elements: + *

+var tb = new Ext.Toolbar({
+    renderTo: document.body,
+    width: 600,
+    height: 100,
+    items: [
+        {
+            // xtype: 'button', // default for Toolbars, same as 'tbbutton'
+            text: 'Button'
+        },
+        {
+            xtype: 'splitbutton', // same as 'tbsplitbutton'
+            text: 'Split Button'
+        },
+        // begin using the right-justified button container
+        '->', // same as {xtype: 'tbfill'}, // Ext.Toolbar.Fill
+        {
+            xtype: 'textfield',
+            name: 'field1',
+            emptyText: 'enter search term'
+        },
+        // add a vertical separator bar between toolbar items
+        '-', // same as {xtype: 'tbseparator'} to create Ext.Toolbar.Separator
+        'text 1', // same as {xtype: 'tbtext', text: 'text1'} to create Ext.Toolbar.TextItem
+        {xtype: 'tbspacer'},// same as ' ' to create Ext.Toolbar.Spacer
+        'text 2',
+        {xtype: 'tbspacer', width: 50}, // add a 50px space
+        'text 3'
+    ]
+});
+ * 
+ * Example adding a ComboBox within a menu of a button: + *

+// ComboBox creation
+var combo = new Ext.form.ComboBox({
+    store: new Ext.data.ArrayStore({
+        autoDestroy: true,
+        fields: ['initials', 'fullname'],
+        data : [
+            ['FF', 'Fred Flintstone'],
+            ['BR', 'Barney Rubble']
+        ]
+    }),
+    displayField: 'fullname',
+    typeAhead: true,
+    mode: 'local',
+    forceSelection: true,
+    triggerAction: 'all',
+    emptyText: 'Select a name...',
+    selectOnFocus: true,
+    width: 135,
+    getListParent: function() {
+        return this.el.up('.x-menu');
+    },
+    iconCls: 'no-icon' //use iconCls if placing within menu to shift to right side of menu
+});
+
+// put ComboBox in a Menu
+var menu = new Ext.menu.Menu({
+    id: 'mainMenu',
+    items: [
+        combo // A Field in a Menu
+    ]
+});
+
+// add a Button with the menu
+tb.add({
+        text:'Button w/ Menu',
+        menu: menu  // assign menu by instance
+    });
+tb.doLayout();
+ * 
+ * @constructor + * Creates a new Toolbar + * @param {Object/Array} config A config object or an array of buttons to {@link #add} + * @xtype toolbar + */ +Ext.Toolbar = function(config){ + if(Ext.isArray(config)){ + config = {items: config, layout: 'toolbar'}; + } else { + config = Ext.apply({ + layout: 'toolbar' + }, config); + if(config.buttons) { + config.items = config.buttons; + } + } + Ext.Toolbar.superclass.constructor.call(this, config); +}; + +(function(){ + +var T = Ext.Toolbar; + +Ext.extend(T, Ext.Container, { + + defaultType: 'button', + +
/** + * @cfg {String/Object} layout + * This class assigns a default layout (layout:'toolbar'). + * Developers may override this configuration option if another layout + * is required (the constructor must be passed a configuration object in this + * case instead of an array). + * See {@link Ext.Container#layout} for additional information. + */ + + trackMenus : true, + internalDefaults: {removeMode: 'container', hideParent: true}, + toolbarCls: 'x-toolbar', + + initComponent : function(){ + T.superclass.initComponent.call(this); + +
/** + * @event overflowchange + * Fires after the overflow state has changed. + * @param {Object} c The Container + * @param {Boolean} lastOverflow overflow state + */ + this.addEvents('overflowchange'); + }, + + // private + onRender : function(ct, position){ + if(!this.el){ + if(!this.autoCreate){ + this.autoCreate = { + cls: this.toolbarCls + ' x-small-editor' + }; + } + this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position); + } + }, + +
/** + *

Adds element(s) to the toolbar -- this function takes a variable number of + * arguments of mixed type and adds them to the toolbar.

+ *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Mixed} arg1 The following types of arguments are all valid:
+ * + * @param {Mixed} arg2 + * @param {Mixed} etc. + * @method add + */ + + // private + lookupComponent : function(c){ + if(Ext.isString(c)){ + if(c == '-'){ + c = new T.Separator(); + }else if(c == ' '){ + c = new T.Spacer(); + }else if(c == '->'){ + c = new T.Fill(); + }else{ + c = new T.TextItem(c); + } + this.applyDefaults(c); + }else{ + if(c.isFormField || c.render){ // some kind of form field, some kind of Toolbar.Item + c = this.constructItem(c); + }else if(c.tag){ // DomHelper spec + c = new T.Item({autoEl: c}); + }else if(c.tagName){ // element + c = new T.Item({el:c}); + }else if(Ext.isObject(c)){ // must be button config? + c = c.xtype ? this.constructItem(c) : this.constructButton(c); + } + } + return c; + }, + + // private + applyDefaults : function(c){ + if(!Ext.isString(c)){ + c = Ext.Toolbar.superclass.applyDefaults.call(this, c); + var d = this.internalDefaults; + if(c.events){ + Ext.applyIf(c.initialConfig, d); + Ext.apply(c, d); + }else{ + Ext.applyIf(c, d); + } + } + return c; + }, + + // private + constructItem : function(item, type){ + return Ext.create(item, type || this.defaultType); + }, + +
/** + * Adds a separator + *

Note: See the notes within {@link Ext.Container#add}.

+ * @return {Ext.Toolbar.Item} The separator {@link Ext.Toolbar.Item item} + */ + addSeparator : function(){ + return this.add(new T.Separator()); + }, + +
/** + * Adds a spacer element + *

Note: See the notes within {@link Ext.Container#add}.

+ * @return {Ext.Toolbar.Spacer} The spacer item + */ + addSpacer : function(){ + return this.add(new T.Spacer()); + }, + +
/** + * Forces subsequent additions into the float:right toolbar + *

Note: See the notes within {@link Ext.Container#add}.

+ */ + addFill : function(){ + this.add(new T.Fill()); + }, + +
/** + * Adds any standard HTML element to the toolbar + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Mixed} el The element or id of the element to add + * @return {Ext.Toolbar.Item} The element's item + */ + addElement : function(el){ + return this.addItem(new T.Item({el:el})); + }, + +
/** + * Adds any Toolbar.Item or subclass + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Ext.Toolbar.Item} item + * @return {Ext.Toolbar.Item} The item + */ + addItem : function(item){ + return Ext.Toolbar.superclass.add.apply(this, arguments); + }, + +
/** + * Adds a button (or buttons). See {@link Ext.Button} for more info on the config. + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Object/Array} config A button config or array of configs + * @return {Ext.Button/Array} + */ + addButton : function(config){ + if(Ext.isArray(config)){ + var buttons = []; + for(var i = 0, len = config.length; i < len; i++) { + buttons.push(this.addButton(config[i])); + } + return buttons; + } + return this.add(this.constructButton(config)); + }, + +
/** + * Adds text to the toolbar + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {String} text The text to add + * @return {Ext.Toolbar.Item} The element's item + */ + addText : function(text){ + return this.addItem(new T.TextItem(text)); + }, + +
/** + * Adds a new element to the toolbar from the passed {@link Ext.DomHelper} config + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Object} config + * @return {Ext.Toolbar.Item} The element's item + */ + addDom : function(config){ + return this.add(new T.Item({autoEl: config})); + }, + +
/** + * Adds a dynamically rendered Ext.form field (TextField, ComboBox, etc). Note: the field should not have + * been rendered yet. For a field that has already been rendered, use {@link #addElement}. + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Ext.form.Field} field + * @return {Ext.Toolbar.Item} + */ + addField : function(field){ + return this.add(field); + }, + +
/** + * Inserts any {@link Ext.Toolbar.Item}/{@link Ext.Button} at the specified index. + *

Note: See the notes within {@link Ext.Container#add}.

+ * @param {Number} index The index where the item is to be inserted + * @param {Object/Ext.Toolbar.Item/Ext.Button/Array} item The button, or button config object to be + * inserted, or an array of buttons/configs. + * @return {Ext.Button/Item} + */ + insertButton : function(index, item){ + if(Ext.isArray(item)){ + var buttons = []; + for(var i = 0, len = item.length; i < len; i++) { + buttons.push(this.insertButton(index + i, item[i])); + } + return buttons; + } + return Ext.Toolbar.superclass.insert.call(this, index, item); + }, + + // private + initMenuTracking : function(item){ + if(this.trackMenus && item.menu){ + this.mon(item, { + 'menutriggerover' : this.onButtonTriggerOver, + 'menushow' : this.onButtonMenuShow, + 'menuhide' : this.onButtonMenuHide, + scope: this + }); + } + }, + + // private + constructButton : function(item){ + var b = item.events ? item : this.constructItem(item, item.split ? 'splitbutton' : this.defaultType); + this.initMenuTracking(b); + return b; + }, + + // private + onDisable : function(){ + this.items.each(function(item){ + if(item.disable){ + item.disable(); + } + }); + }, + + // private + onEnable : function(){ + this.items.each(function(item){ + if(item.enable){ + item.enable(); + } + }); + }, + + // private + onButtonTriggerOver : function(btn){ + if(this.activeMenuBtn && this.activeMenuBtn != btn){ + this.activeMenuBtn.hideMenu(); + btn.showMenu(); + this.activeMenuBtn = btn; + } + }, + + // private + onButtonMenuShow : function(btn){ + this.activeMenuBtn = btn; + }, + + // private + onButtonMenuHide : function(btn){ + delete this.activeMenuBtn; + } +}); +Ext.reg('toolbar', Ext.Toolbar); + +
/** + * @class Ext.Toolbar.Item + * @extends Ext.BoxComponent + * The base class that other non-interacting Toolbar Item classes should extend in order to + * get some basic common toolbar item functionality. + * @constructor + * Creates a new Item + * @param {HTMLElement} el + * @xtype tbitem + */ +T.Item = Ext.extend(Ext.BoxComponent, { + hideParent: true, // Hiding a Toolbar.Item hides its containing TD + enable:Ext.emptyFn, + disable:Ext.emptyFn, + focus:Ext.emptyFn +
/** + * @cfg {String} overflowText Text to be used for the menu if the item is overflowed. + */ +}); +Ext.reg('tbitem', T.Item); + +
/** + * @class Ext.Toolbar.Separator + * @extends Ext.Toolbar.Item + * A simple class that adds a vertical separator bar between toolbar items + * (css class:'xtb-sep'). Example usage: + *

+new Ext.Panel({
+    tbar : [
+        'Item 1',
+        {xtype: 'tbseparator'}, // or '-'
+        'Item 2'
+    ]
+});
+
+ * @constructor + * Creates a new Separator + * @xtype tbseparator + */ +T.Separator = Ext.extend(T.Item, { + onRender : function(ct, position){ + this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position); + } +}); +Ext.reg('tbseparator', T.Separator); + +
/** + * @class Ext.Toolbar.Spacer + * @extends Ext.Toolbar.Item + * A simple element that adds extra horizontal space between items in a toolbar. + * By default a 2px wide space is added via css specification:

+.x-toolbar .xtb-spacer {
+    width:2px;
+}
+ * 
+ *

Example usage:

+ *

+new Ext.Panel({
+    tbar : [
+        'Item 1',
+        {xtype: 'tbspacer'}, // or ' '
+        'Item 2',
+        // space width is also configurable via javascript
+        {xtype: 'tbspacer', width: 50}, // add a 50px space
+        'Item 3'
+    ]
+});
+
+ * @constructor + * Creates a new Spacer + * @xtype tbspacer + */ +T.Spacer = Ext.extend(T.Item, { +
/** + * @cfg {Number} width + * The width of the spacer in pixels (defaults to 2px via css style .x-toolbar .xtb-spacer). + */ + + onRender : function(ct, position){ + this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position); + } +}); +Ext.reg('tbspacer', T.Spacer); + +
/** + * @class Ext.Toolbar.Fill + * @extends Ext.Toolbar.Spacer + * A non-rendering placeholder item which instructs the Toolbar's Layout to begin using + * the right-justified button container. + *

+new Ext.Panel({
+    tbar : [
+        'Item 1',
+        {xtype: 'tbfill'}, // or '->'
+        'Item 2'
+    ]
+});
+
+ * @constructor + * Creates a new Fill + * @xtype tbfill + */ +T.Fill = Ext.extend(T.Item, { + // private + render : Ext.emptyFn, + isFill : true +}); +Ext.reg('tbfill', T.Fill); + +
/** + * @class Ext.Toolbar.TextItem + * @extends Ext.Toolbar.Item + * A simple class that renders text directly into a toolbar + * (with css class:'xtb-text'). Example usage: + *

+new Ext.Panel({
+    tbar : [
+        {xtype: 'tbtext', text: 'Item 1'} // or simply 'Item 1'
+    ]
+});
+
+ * @constructor + * Creates a new TextItem + * @param {String/Object} text A text string, or a config object containing a text property + * @xtype tbtext + */ +T.TextItem = Ext.extend(T.Item, { + constructor: function(config){ + if (Ext.isString(config)) { + config = { autoEl: {cls: 'xtb-text', html: config }}; + } else { + config.autoEl = {cls: 'xtb-text', html: config.text || ''}; + } + T.TextItem.superclass.constructor.call(this, config); + }, +
/** + * Updates this item's text, setting the text to be used as innerHTML. + * @param {String} t The text to display (html accepted). + */ + setText : function(t) { + if (this.rendered) { + this.el.dom.innerHTML = t; + } else { + this.autoEl.html = t; + } + } +}); +Ext.reg('tbtext', T.TextItem); + +// backwards compat +T.Button = Ext.extend(Ext.Button, {}); +T.SplitButton = Ext.extend(Ext.SplitButton, {}); +Ext.reg('tbbutton', T.Button); +Ext.reg('tbsplit', T.SplitButton); + +})(); +
+ + \ No newline at end of file