/ext-4.1.0_b3/docs/extjs/examples/ux/TabCloseMenu.js
JavaScript | 211 lines | 138 code | 38 blank | 35 comment | 18 complexity | bf3a377fae7450ff453d6d3d1ad08f07 MD5 | raw file
1/**
2 * Plugin for adding a close context menu to tabs. Note that the menu respects
3 * the closable configuration on the tab. As such, commands like remove others
4 * and remove all will not remove items that are not closable.
5 */
6Ext.define('Ext.ux.TabCloseMenu', {
7 alias: 'plugin.tabclosemenu',
8
9 mixins: {
10 observable: 'Ext.util.Observable'
11 },
12
13 /**
14 * @cfg {String} closeTabText
15 * The text for closing the current tab.
16 */
17 closeTabText: 'Close Tab',
18
19 /**
20 * @cfg {Boolean} showCloseOthers
21 * Indicates whether to show the 'Close Others' option.
22 */
23 showCloseOthers: true,
24
25 /**
26 * @cfg {String} closeOtherTabsText
27 * The text for closing all tabs except the current one.
28 */
29 closeOthersTabsText: 'Close Other Tabs',
30
31 /**
32 * @cfg {Boolean} showCloseAll
33 * Indicates whether to show the 'Close All' option.
34 */
35 showCloseAll: true,
36
37 /**
38 * @cfg {String} closeAllTabsText
39 * <p>The text for closing all tabs.
40 */
41 closeAllTabsText: 'Close All Tabs',
42
43 /**
44 * @cfg {Array} extraItemsHead
45 * An array of additional context menu items to add to the front of the context menu.
46 */
47 extraItemsHead: null,
48
49 /**
50 * @cfg {Array} extraItemsTail
51 * An array of additional context menu items to add to the end of the context menu.
52 */
53 extraItemsTail: null,
54
55 //public
56 constructor: function (config) {
57 this.addEvents(
58 'aftermenu',
59 'beforemenu');
60
61 this.mixins.observable.constructor.call(this, config);
62 },
63
64 init : function(tabpanel){
65 this.tabPanel = tabpanel;
66 this.tabBar = tabpanel.down("tabbar");
67
68 this.mon(this.tabPanel, {
69 scope: this,
70 afterlayout: this.onAfterLayout,
71 single: true
72 });
73 },
74
75 onAfterLayout: function() {
76 this.mon(this.tabBar.el, {
77 scope: this,
78 contextmenu: this.onContextMenu,
79 delegate: 'div.x-tab'
80 });
81 },
82
83 onBeforeDestroy : function(){
84 Ext.destroy(this.menu);
85 this.callParent(arguments);
86 },
87
88 // private
89 onContextMenu : function(event, target){
90 var me = this,
91 menu = me.createMenu(),
92 disableAll = true,
93 disableOthers = true,
94 tab = me.tabBar.getChildByElement(target),
95 index = me.tabBar.items.indexOf(tab);
96
97 me.item = me.tabPanel.getComponent(index);
98 menu.child('*[text="' + me.closeTabText + '"]').setDisabled(!me.item.closable);
99
100 if (me.showCloseAll || me.showCloseOthers) {
101 me.tabPanel.items.each(function(item) {
102 if (item.closable) {
103 disableAll = false;
104 if (item != me.item) {
105 disableOthers = false;
106 return false;
107 }
108 }
109 return true;
110 });
111
112 if (me.showCloseAll) {
113 menu.child('*[text="' + me.closeAllTabsText + '"]').setDisabled(disableAll);
114 }
115
116 if (me.showCloseOthers) {
117 menu.child('*[text="' + me.closeOthersTabsText + '"]').setDisabled(disableOthers);
118 }
119 }
120
121 event.preventDefault();
122 me.fireEvent('beforemenu', menu, me.item, me);
123
124 menu.showAt(event.getXY());
125 },
126
127 createMenu : function() {
128 var me = this;
129
130 if (!me.menu) {
131 var items = [{
132 text: me.closeTabText,
133 scope: me,
134 handler: me.onClose
135 }];
136
137 if (me.showCloseAll || me.showCloseOthers) {
138 items.push('-');
139 }
140
141 if (me.showCloseOthers) {
142 items.push({
143 text: me.closeOthersTabsText,
144 scope: me,
145 handler: me.onCloseOthers
146 });
147 }
148
149 if (me.showCloseAll) {
150 items.push({
151 text: me.closeAllTabsText,
152 scope: me,
153 handler: me.onCloseAll
154 });
155 }
156
157 if (me.extraItemsHead) {
158 items = me.extraItemsHead.concat(items);
159 }
160
161 if (me.extraItemsTail) {
162 items = items.concat(me.extraItemsTail);
163 }
164
165 me.menu = Ext.create('Ext.menu.Menu', {
166 items: items,
167 listeners: {
168 hide: me.onHideMenu,
169 scope: me
170 }
171 });
172 }
173
174 return me.menu;
175 },
176
177 onHideMenu: function () {
178 var me = this;
179
180 me.item = null;
181 me.fireEvent('aftermenu', me.menu, me);
182 },
183
184 onClose : function(){
185 this.tabPanel.remove(this.item);
186 },
187
188 onCloseOthers : function(){
189 this.doClose(true);
190 },
191
192 onCloseAll : function(){
193 this.doClose(false);
194 },
195
196 doClose : function(excludeActive){
197 var items = [];
198
199 this.tabPanel.items.each(function(item){
200 if(item.closable){
201 if(!excludeActive || item != this.item){
202 items.push(item);
203 }
204 }
205 }, this);
206
207 Ext.each(items, function(item){
208 this.tabPanel.remove(item);
209 }, this);
210 }
211});