3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @author Nicolas Ferrero
17 * @class Ext.ux.GroupTabPanel
18 * @extends Ext.Container
19 * A TabPanel with grouping support.
21 Ext.define('Ext.ux.GroupTabPanel', {
22 extend: 'Ext.Container',
24 alias: 'widget.grouptabpanel',
32 baseCls : Ext.baseCSSPrefix + 'grouptabpanel',
34 initComponent: function(config) {
38 Ext.apply(me, config);
40 me.store = me.createItemsStore();
50 me.items = Ext.each(me.items, function(item) {
51 items.push(item.items);
56 cls: 'x-tree-panel x-grouptabbar',
72 renderer: function (value, cell, node, idx1, idx2, store, tree) {
75 if (!node.data.activeGroup) {
76 cls += ' x-inactive-group';
77 } else if (node.parentNode && node.parentNode.parentNode === null) {
78 cls += ' x-grouptab-first';
79 if (node.previousSibling) {
80 cls += ' x-grouptab-prev';
82 } else if (node.nextSibling === null) {
83 cls += ' x-grouptab-last';
85 cls += ' x-grouptab-center';
87 if (node.data.activeTab) {
88 cls += ' x-active-tab';
90 cell.tdCls= 'x-grouptab'+ cls;
99 activeItem: me.mainItem,
100 baseCls: Ext.baseCSSPrefix + 'grouptabcontainer',
106 * @event beforetabchange
107 * Fires before a tab change (activated by {@link #setActiveTab}). Return false in any listener to cancel
109 * @param {Ext.ux.GroupTabPanel} grouptabPanel The GroupTabPanel
110 * @param {Ext.Component} newCard The card that is about to be activated
111 * @param {Ext.Component} oldCard The card that is currently active
117 * Fires when a new tab has been activated (activated by {@link #setActiveTab}).
118 * @param {Ext.ux.GroupTabPanel} grouptabPanel The GroupTabPanel
119 * @param {Ext.Component} newCard The newly activated item
120 * @param {Ext.Component} oldCard The previously active item
125 * @event beforegroupchange
126 * Fires before a group change (activated by {@link #setActiveGroup}). Return false in any listener to cancel
128 * @param {Ext.ux.GroupTabPanel} grouptabPanel The GroupTabPanel
129 * @param {Ext.Component} newGroup The root group card that is about to be activated
130 * @param {Ext.Component} oldGroup The root group card that is currently active
136 * Fires when a new group has been activated (activated by {@link #setActiveGroup}).
137 * @param {Ext.ux.GroupTabPanel} grouptabPanel The GroupTabPanel
138 * @param {Ext.Component} newGroup The newly activated root group item
139 * @param {Ext.Component} oldGroup The previously active root group item
144 me.callParent(arguments);
145 me.setActiveTab(me.activeTab);
146 me.setActiveGroup(me.activeGroup);
147 me.mon(me.down('treepanel').getSelectionModel(), 'select', me.onNodeSelect, me);
152 * Node selection listener.
154 onNodeSelect: function (selModel, node) {
156 currentNode = me.store.getRootNode(),
159 if (node.parentNode && node.parentNode.parentNode === null) {
162 parent = node.parentNode;
165 if (me.setActiveGroup(parent.get('id')) === false || me.setActiveTab(node.get('id')) === false) {
170 currentNode.set('activeTab', false);
171 currentNode.set('activeGroup', false);
172 currentNode = currentNode.firstChild || currentNode.nextSibling || currentNode.parentNode.nextSibling;
175 parent.set('activeGroup', true);
177 parent.eachChild(function(child) {
179 child.set('activeGroup', true);
181 node.set('activeTab', true);
182 selModel.view.refresh();
186 * Makes the given component active (makes it the visible card in the GroupTabPanel's CardLayout)
187 * @param {Ext.Component} cmp The component to make active
189 setActiveTab: function(cmp) {
194 if(Ext.isString(cmp)) {
195 newTab = Ext.getCmp(newTab);
198 if (newTab === me.activeTab) {
202 oldTab = me.activeTab;
203 if (me.fireEvent('beforetabchange', me, newTab, oldTab) !== false) {
204 me.activeTab = newTab;
206 me.down('container[baseCls=' + Ext.baseCSSPrefix + 'grouptabcontainer' + ']').getLayout().setActiveItem(newTab);
208 me.fireEvent('tabchange', me, newTab, oldTab);
214 * Makes the given group active
215 * @param {Ext.Component} cmp The root component to make active.
217 setActiveGroup: function(cmp) {
222 if(Ext.isString(cmp)) {
223 newGroup = Ext.getCmp(newGroup);
226 if (newGroup === me.activeGroup) {
230 oldGroup = me.activeGroup;
231 if (me.fireEvent('beforegroupchange', me, newGroup, oldGroup) !== false) {
232 me.activeGroup = newGroup;
233 me.fireEvent('groupchange', me, newGroup, oldGroup);
242 * Creates the TreeStore used by the GroupTabBar.
244 createItemsStore: function() {
250 me.activeGroup = me.activeGroup || 0;
252 Ext.each(me.items, function(item, idx){
253 var items = item.items,
254 rootItem = (items[item.mainItem] || items[0]),
260 rootItem.id = Ext.id();
263 root.id = rootItem.id;
264 root.text = rootItem.title;
265 root.iconCls = rootItem.iconCls;
266 delete rootItem.iconCls;
267 delete rootItem.title;
268 root.expanded = true;
269 root.activeGroup = (me.activeGroup === idx);
270 root.activeTab = root.activeGroup ? true : false;
271 if (root.activeTab) {
272 me.activeTab = root.id;
275 if (root.activeGroup) {
276 me.mainItem = item.mainItem || 0;
277 me.activeGroup = root.id;
280 Ext.each(item.items, function(childItem) {
282 childItem.id = Ext.id();
284 if(childItem.id !== root.id) {
288 text: childItem.title,
289 iconCls: childItem.iconCls,
292 delete childItem.title;
293 delete childItem.iconCls;
295 child.activeGroup = root.activeGroup;
296 root.children.push(child);
300 data.children.push(root);
304 return Ext.create('Ext.data.TreeStore', {
305 fields: ['id', 'text', 'activeGroup', 'activeTab'],
306 root: {expanded: true},
315 * Returns the item that is currently active inside this GroupTabPanel.
316 * @return {Ext.Component/Integer} The currently active item
318 getActiveTab: function() {
319 return this.activeTab;
323 * Returns the root group item that is currently active inside this GroupTabPanel.
324 * @return {Ext.Component/Integer} The currently active root group item
326 getActiveGroup: function() {
327 return this.activeGroup;