Upgrade to ExtJS 3.2.2 - Released 06/02/2010
[extjs.git] / examples / ux / GroupTab.js
1 /*!
2  * Ext JS Library 3.2.2
3  * Copyright(c) 2006-2010 Ext JS, Inc.
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 Ext.ux.GroupTab = Ext.extend(Ext.Container, {
8     mainItem: 0,
9     
10     expanded: true,
11     
12     deferredRender: true,
13     
14     activeTab: null,
15     
16     idDelimiter: '__',
17     
18     headerAsText: false,
19     
20     frame: false,
21     
22     hideBorders: true,
23     
24     initComponent: function(config){
25         Ext.apply(this, config);
26         this.frame = false;
27         
28         Ext.ux.GroupTab.superclass.initComponent.call(this);
29         
30         this.addEvents('activate', 'deactivate', 'changemainitem', 'beforetabchange', 'tabchange');
31         
32         this.setLayout(new Ext.layout.CardLayout({
33             deferredRender: this.deferredRender
34         }));
35         
36         if (!this.stack) {
37             this.stack = Ext.TabPanel.AccessStack();
38         }
39         
40         this.initItems();
41         
42         this.on('beforerender', function(){
43             this.groupEl = this.ownerCt.getGroupEl(this);
44         }, this);
45         
46         this.on('add', this.onAdd, this, {
47             target: this
48         });
49         this.on('remove', this.onRemove, this, {
50             target: this
51         });
52         
53         if (this.mainItem !== undefined) {
54             var item = (typeof this.mainItem == 'object') ? this.mainItem : this.items.get(this.mainItem);
55             delete this.mainItem;
56             this.setMainItem(item);
57         }
58     },
59     
60     /**
61      * Sets the specified tab as the active tab. This method fires the {@link #beforetabchange} event which
62      * can return false to cancel the tab change.
63      * @param {String/Panel} tab The id or tab Panel to activate
64      */
65     setActiveTab : function(item){
66         item = this.getComponent(item);
67         if(!item){
68             return false;
69         }
70         if(!this.rendered){
71             this.activeTab = item;
72             return true;
73         }
74         if(this.activeTab != item && this.fireEvent('beforetabchange', this, item, this.activeTab) !== false){
75             if(this.activeTab && this.activeTab != this.mainItem){
76                 var oldEl = this.getTabEl(this.activeTab);
77                 if(oldEl){
78                     Ext.fly(oldEl).removeClass('x-grouptabs-strip-active');
79                 }
80             }
81             var el = this.getTabEl(item);
82             Ext.fly(el).addClass('x-grouptabs-strip-active');
83             this.activeTab = item;
84             this.stack.add(item);
85
86             this.layout.setActiveItem(item);
87             if(this.layoutOnTabChange && item.doLayout){
88                 item.doLayout();
89             }
90             if(this.scrolling){
91                 this.scrollToTab(item, this.animScroll);
92             }
93
94             this.fireEvent('tabchange', this, item);
95             return true;
96         }
97         return false;
98     },
99     
100     getTabEl: function(item){
101         if (item == this.mainItem) {
102             return this.groupEl;
103         }
104         return Ext.TabPanel.prototype.getTabEl.call(this, item);
105     },
106     
107     onRender: function(ct, position){
108         Ext.ux.GroupTab.superclass.onRender.call(this, ct, position);
109         
110         this.strip = Ext.fly(this.groupEl).createChild({
111             tag: 'ul',
112             cls: 'x-grouptabs-sub'
113         });
114
115         this.tooltip = new Ext.ToolTip({
116            target: this.groupEl,
117            delegate: 'a.x-grouptabs-text',
118            trackMouse: true,
119            renderTo: document.body,
120            listeners: {
121                beforeshow: function(tip) {
122                    var item = (tip.triggerElement.parentNode === this.mainItem.tabEl)
123                        ? this.mainItem
124                        : this.findById(tip.triggerElement.parentNode.id.split(this.idDelimiter)[1]);
125
126                    if(!item.tabTip) {
127                        return false;
128                    }
129                    tip.body.dom.innerHTML = item.tabTip;
130                },
131                scope: this
132            }
133         });
134                 
135         if (!this.itemTpl) {
136             var tt = new Ext.Template('<li class="{cls}" id="{id}">', '<a onclick="return false;" class="x-grouptabs-text {iconCls}">{text}</a>', '</li>');
137             tt.disableFormats = true;
138             tt.compile();
139             Ext.ux.GroupTab.prototype.itemTpl = tt;
140         }
141         
142         this.items.each(this.initTab, this);
143     },
144     
145     afterRender: function(){
146         Ext.ux.GroupTab.superclass.afterRender.call(this);
147         
148         if (this.activeTab !== undefined) {
149             var item = (typeof this.activeTab == 'object') ? this.activeTab : this.items.get(this.activeTab);
150             delete this.activeTab;
151             this.setActiveTab(item);
152         }
153     },
154     
155     // private
156     initTab: function(item, index){
157         var before = this.strip.dom.childNodes[index];
158         var p = Ext.TabPanel.prototype.getTemplateArgs.call(this, item);
159         
160         if (item === this.mainItem) {
161             item.tabEl = this.groupEl;
162             p.cls += ' x-grouptabs-main-item';
163         }
164         
165         var el = before ? this.itemTpl.insertBefore(before, p) : this.itemTpl.append(this.strip, p);
166         
167         item.tabEl = item.tabEl || el;
168                 
169         item.on('disable', this.onItemDisabled, this);
170         item.on('enable', this.onItemEnabled, this);
171         item.on('titlechange', this.onItemTitleChanged, this);
172         item.on('iconchange', this.onItemIconChanged, this);
173         item.on('beforeshow', this.onBeforeShowItem, this);
174     },
175     
176     setMainItem: function(item){
177         item = this.getComponent(item);
178         if (!item || this.fireEvent('changemainitem', this, item, this.mainItem) === false) {
179             return;
180         }
181         
182         this.mainItem = item;
183     },
184     
185     getMainItem: function(){
186         return this.mainItem || null;
187     },
188     
189     // private
190     onBeforeShowItem: function(item){
191         if (item != this.activeTab) {
192             this.setActiveTab(item);
193             return false;
194         }
195     },
196     
197     // private
198     onAdd: function(gt, item, index){
199         if (this.rendered) {
200             this.initTab.call(this, item, index);
201         }
202     },
203     
204     // private
205     onRemove: function(tp, item){
206         Ext.destroy(Ext.get(this.getTabEl(item)));
207         this.stack.remove(item);
208         item.un('disable', this.onItemDisabled, this);
209         item.un('enable', this.onItemEnabled, this);
210         item.un('titlechange', this.onItemTitleChanged, this);
211         item.un('iconchange', this.onItemIconChanged, this);
212         item.un('beforeshow', this.onBeforeShowItem, this);
213         if (item == this.activeTab) {
214             var next = this.stack.next();
215             if (next) {
216                 this.setActiveTab(next);
217             }
218             else if (this.items.getCount() > 0) {
219                 this.setActiveTab(0);
220             }
221             else {
222                 this.activeTab = null;
223             }
224         }
225     },
226     
227     // private
228     onBeforeAdd: function(item){
229         var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
230         if (existing) {
231             this.setActiveTab(item);
232             return false;
233         }
234         Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
235         var es = item.elements;
236         item.elements = es ? es.replace(',header', '') : es;
237         item.border = (item.border === true);
238     },
239     
240     // private
241     onItemDisabled: Ext.TabPanel.prototype.onItemDisabled,
242     onItemEnabled: Ext.TabPanel.prototype.onItemEnabled,
243     
244     // private
245     onItemTitleChanged: function(item){
246         var el = this.getTabEl(item);
247         if (el) {
248             Ext.fly(el).child('a.x-grouptabs-text', true).innerHTML = item.title;
249         }
250     },
251     
252     //private
253     onItemIconChanged: function(item, iconCls, oldCls){
254         var el = this.getTabEl(item);
255         if (el) {
256             Ext.fly(el).child('a.x-grouptabs-text').replaceClass(oldCls, iconCls);
257         }
258     },
259     
260     beforeDestroy: function(){
261         Ext.TabPanel.prototype.beforeDestroy.call(this);
262         this.tooltip.destroy();
263     }
264 });
265
266 Ext.reg('grouptab', Ext.ux.GroupTab);