]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * Tab Panels are a great way to allow the user to switch between several pages that are all full screen. Each\r | |
3 | * Component in the Tab Panel gets its own Tab, which shows the Component when tapped on. Tabs can be positioned at\r | |
4 | * the top or the bottom of the Tab Panel, and can optionally accept title and icon \r | |
5 | * configurations (see {@link Ext.Button#iconCls iconCls} for additional information).\r | |
6 | *\r | |
7 | * Here's how we can set up a simple Tab Panel with tabs at the bottom. Use the controls at the top left of the example\r | |
8 | * to toggle between code mode and live preview mode (you can also edit the code and see your changes in the live\r | |
9 | * preview):\r | |
10 | *\r | |
11 | * @example miniphone preview\r | |
12 | * Ext.create('Ext.TabPanel', {\r | |
13 | * fullscreen: true,\r | |
14 | * tabBarPosition: 'bottom',\r | |
15 | *\r | |
16 | * defaults: {\r | |
17 | * styleHtmlContent: true\r | |
18 | * },\r | |
19 | *\r | |
20 | * items: [\r | |
21 | * {\r | |
22 | * title: 'Home',\r | |
23 | * iconCls: 'home',\r | |
24 | * html: 'Home Screen'\r | |
25 | * },\r | |
26 | * {\r | |
27 | * title: 'Contact',\r | |
28 | * iconCls: 'user',\r | |
29 | * html: 'Contact Screen'\r | |
30 | * }\r | |
31 | * ]\r | |
32 | * });\r | |
33 | * One tab was created for each of the {@link Ext.Panel panels} defined in the items array. Each tab automatically uses\r | |
34 | * the title and icon defined on the item configuration, and switches to that item when tapped on. We can also position\r | |
35 | * the tab bar at the top, which makes our Tab Panel look like this:\r | |
36 | *\r | |
37 | * @example miniphone preview\r | |
38 | * Ext.create('Ext.TabPanel', {\r | |
39 | * fullscreen: true,\r | |
40 | *\r | |
41 | * defaults: {\r | |
42 | * styleHtmlContent: true\r | |
43 | * },\r | |
44 | *\r | |
45 | * items: [\r | |
46 | * {\r | |
47 | * title: 'Home',\r | |
48 | * html: 'Home Screen'\r | |
49 | * },\r | |
50 | * {\r | |
51 | * title: 'Contact',\r | |
52 | * html: 'Contact Screen'\r | |
53 | * }\r | |
54 | * ]\r | |
55 | * });\r | |
56 | *\r | |
57 | */\r | |
58 | Ext.define('Ext.tab.Panel', {\r | |
59 | extend: 'Ext.Container',\r | |
60 | xtype : 'tabpanel',\r | |
61 | alternateClassName: 'Ext.TabPanel',\r | |
62 | \r | |
63 | requires: ['Ext.tab.Bar'],\r | |
64 | \r | |
65 | config: {\r | |
66 | /**\r | |
67 | * @cfg {Object} tabBar\r | |
68 | * An Ext.tab.Bar configuration.\r | |
69 | * @accessor\r | |
70 | */\r | |
71 | tabBar: true,\r | |
72 | \r | |
73 | /**\r | |
74 | * @cfg {String} tabBarPosition\r | |
75 | * The docked position for the {@link #tabBar} instance.\r | |
76 | * Possible values are 'top' and 'bottom'.\r | |
77 | * @accessor\r | |
78 | */\r | |
79 | tabBarPosition: 'top',\r | |
80 | \r | |
81 | /**\r | |
82 | * @cfg layout\r | |
83 | * @inheritdoc\r | |
84 | */\r | |
85 | layout: {\r | |
86 | type: 'card',\r | |
87 | animation: {\r | |
88 | type: 'slide',\r | |
89 | direction: 'left'\r | |
90 | }\r | |
91 | },\r | |
92 | \r | |
93 | /**\r | |
94 | * @cfg cls\r | |
95 | * @inheritdoc\r | |
96 | */\r | |
97 | cls: Ext.baseCSSPrefix + 'tabpanel'\r | |
98 | \r | |
99 | /**\r | |
100 | * @cfg {Boolean/String/Object} scrollable\r | |
101 | * @accessor\r | |
102 | * @hide\r | |
103 | */\r | |
104 | \r | |
105 | /**\r | |
106 | * @cfg {Boolean/String/Object} scroll\r | |
107 | */\r | |
108 | },\r | |
109 | \r | |
110 | initialize: function() {\r | |
111 | this.callParent();\r | |
112 | \r | |
113 | this.on({\r | |
114 | beforeactivetabchange: 'doTabChange',\r | |
115 | delegate: '> tabbar',\r | |
116 | scope : this\r | |
117 | });\r | |
118 | \r | |
119 | this.on({\r | |
120 | disabledchange: 'onItemDisabledChange',\r | |
121 | delegate: '> component',\r | |
122 | scope : this\r | |
123 | });\r | |
124 | },\r | |
125 | \r | |
126 | /**\r | |
127 | * Tab panels should not be scrollable. Instead, you should add scrollable to any item that\r | |
128 | * you want to scroll.\r | |
129 | * @private\r | |
130 | */\r | |
131 | applyScrollable: function() {\r | |
132 | return false;\r | |
133 | },\r | |
134 | \r | |
135 | /**\r | |
136 | * Updates the Ui for this component and the {@link #tabBar}.\r | |
137 | */\r | |
138 | updateUi: function(newUi, oldUi) {\r | |
139 | this.callParent(arguments);\r | |
140 | \r | |
141 | if (this.initialized) {\r | |
142 | this.getTabBar().setUi(newUi);\r | |
143 | }\r | |
144 | },\r | |
145 | \r | |
146 | /**\r | |
147 | * @private\r | |
148 | */\r | |
149 | updateActiveItem: function(newActiveItem, oldActiveItem) {\r | |
150 | if (newActiveItem) {\r | |
151 | var items = this.getInnerItems(),\r | |
152 | oldIndex = items.indexOf(oldActiveItem),\r | |
153 | newIndex = items.indexOf(newActiveItem),\r | |
154 | reverse = oldIndex > newIndex,\r | |
155 | animation = this.getLayout().getAnimation(),\r | |
156 | tabBar = this.getTabBar(),\r | |
157 | oldTab = tabBar.parseActiveTab(oldIndex),\r | |
158 | newTab = tabBar.parseActiveTab(newIndex);\r | |
159 | \r | |
160 | if (animation && animation.setReverse) {\r | |
161 | animation.setReverse(reverse);\r | |
162 | }\r | |
163 | \r | |
164 | this.callParent(arguments);\r | |
165 | \r | |
166 | if (newIndex != -1) {\r | |
167 | this.forcedChange = true;\r | |
168 | tabBar.setActiveTab(newIndex);\r | |
169 | this.forcedChange = false;\r | |
170 | \r | |
171 | if (oldTab) {\r | |
172 | oldTab.setActive(false);\r | |
173 | }\r | |
174 | \r | |
175 | if (newTab) {\r | |
176 | newTab.setActive(true);\r | |
177 | }\r | |
178 | }\r | |
179 | }\r | |
180 | },\r | |
181 | \r | |
182 | /**\r | |
183 | * Updates this container with the new active item.\r | |
184 | * @param {Object} tabBar\r | |
185 | * @param {Object} newTab\r | |
186 | * @return {Boolean}\r | |
187 | */\r | |
188 | doTabChange: function (tabBar, newTab) {\r | |
189 | var oldActiveItem = this.getActiveItem(),\r | |
190 | newActiveItem;\r | |
191 | \r | |
192 | this.setActiveItem(tabBar.indexOf(newTab));\r | |
193 | newActiveItem = this.getActiveItem();\r | |
194 | return this.forcedChange || oldActiveItem !== newActiveItem;\r | |
195 | },\r | |
196 | \r | |
197 | /**\r | |
198 | * Creates a new {@link Ext.tab.Bar} instance using {@link Ext#factory}.\r | |
199 | * @param {Object} config\r | |
200 | * @return {Object}\r | |
201 | * @private\r | |
202 | */\r | |
203 | applyTabBar: function(config) {\r | |
204 | if (config === true) {\r | |
205 | config = {};\r | |
206 | }\r | |
207 | \r | |
208 | if (config) {\r | |
209 | Ext.applyIf(config, {\r | |
210 | ui: this.getUi(),\r | |
211 | docked: this.getTabBarPosition()\r | |
212 | });\r | |
213 | }\r | |
214 | \r | |
215 | return Ext.factory(config, Ext.tab.Bar, this.getTabBar());\r | |
216 | },\r | |
217 | \r | |
218 | /**\r | |
219 | * Adds the new {@link Ext.tab.Bar} instance into this container.\r | |
220 | * @private\r | |
221 | */\r | |
222 | updateTabBar: function(newTabBar) {\r | |
223 | if (newTabBar) {\r | |
224 | this.add(newTabBar);\r | |
225 | this.setTabBarPosition(newTabBar.getDocked());\r | |
226 | }\r | |
227 | },\r | |
228 | \r | |
229 | /**\r | |
230 | * Updates the docked position of the {@link #tabBar}.\r | |
231 | * @private\r | |
232 | */\r | |
233 | updateTabBarPosition: function(position) {\r | |
234 | var tabBar = this.getTabBar();\r | |
235 | if (tabBar) {\r | |
236 | tabBar.setDocked(position);\r | |
237 | }\r | |
238 | },\r | |
239 | \r | |
240 | onItemAdd: function(card) {\r | |
241 | var me = this;\r | |
242 | \r | |
243 | if (!card.isInnerItem()) {\r | |
244 | return me.callParent(arguments);\r | |
245 | }\r | |
246 | \r | |
247 | var tabBar = me.getTabBar(),\r | |
248 | initialConfig = card.getInitialConfig(),\r | |
249 | tabConfig = initialConfig.tab || {},\r | |
250 | tabTitle = (card.getTitle) ? card.getTitle() : initialConfig.title,\r | |
251 | tabIconCls = (card.getIconCls) ? card.getIconCls() : initialConfig.iconCls,\r | |
252 | tabHidden = (card.getHidden) ? card.getHidden() : initialConfig.hidden,\r | |
253 | tabDisabled = (card.getDisabled) ? card.getDisabled() : initialConfig.disabled,\r | |
254 | tabBadgeText = (card.getBadgeText) ? card.getBadgeText() : initialConfig.badgeText,\r | |
255 | innerItems = me.getInnerItems(),\r | |
256 | index = innerItems.indexOf(card),\r | |
257 | tabs = tabBar.getItems(),\r | |
258 | activeTab = tabBar.getActiveTab(),\r | |
259 | currentTabInstance = (tabs.length >= innerItems.length) && tabs.getAt(index),\r | |
260 | header = card.isPanel && card.getHeader(),\r | |
261 | tabInstance;\r | |
262 | \r | |
263 | if (tabTitle && !tabConfig.title) {\r | |
264 | tabConfig.title = tabTitle;\r | |
265 | }\r | |
266 | \r | |
267 | if (tabIconCls && !tabConfig.iconCls) {\r | |
268 | tabConfig.iconCls = tabIconCls;\r | |
269 | }\r | |
270 | \r | |
271 | if (tabHidden && !tabConfig.hidden) {\r | |
272 | tabConfig.hidden = tabHidden;\r | |
273 | }\r | |
274 | \r | |
275 | if (tabDisabled && !tabConfig.disabled) {\r | |
276 | tabConfig.disabled = tabDisabled;\r | |
277 | }\r | |
278 | \r | |
279 | if (tabBadgeText && !tabConfig.badgeText) {\r | |
280 | tabConfig.badgeText = tabBadgeText;\r | |
281 | }\r | |
282 | \r | |
283 | //<debug>\r | |
284 | if (!currentTabInstance && !tabConfig.title && !tabConfig.iconCls) {\r | |
285 | if (!tabConfig.title && !tabConfig.iconCls) {\r | |
286 | Ext.Logger.error('Adding a card to a tab container without specifying any tab configuration');\r | |
287 | }\r | |
288 | }\r | |
289 | //</debug>\r | |
290 | \r | |
291 | tabInstance = Ext.factory(tabConfig, Ext.tab.Tab, currentTabInstance);\r | |
292 | \r | |
293 | if (!currentTabInstance) {\r | |
294 | tabBar.insert(index, tabInstance);\r | |
295 | }\r | |
296 | \r | |
297 | card.tab = tabInstance;\r | |
298 | if (header) {\r | |
299 | header.setHidden(true);\r | |
300 | }\r | |
301 | \r | |
302 | me.callParent(arguments);\r | |
303 | \r | |
304 | if (!activeTab && activeTab !== 0) {\r | |
305 | tabBar.setActiveTab(tabBar.getActiveItem());\r | |
306 | }\r | |
307 | },\r | |
308 | \r | |
309 | /**\r | |
310 | * If an item gets enabled/disabled and it has an tab, we should also enable/disable that tab\r | |
311 | * @private\r | |
312 | */\r | |
313 | onItemDisabledChange: function(item, newDisabled) {\r | |
314 | if (item && item.tab) {\r | |
315 | item.tab.setDisabled(newDisabled);\r | |
316 | }\r | |
317 | },\r | |
318 | \r | |
319 | // @private\r | |
320 | onItemRemove: function(item, index) {\r | |
321 | this.getTabBar().remove(item.tab, this.getAutoDestroy());\r | |
322 | \r | |
323 | this.callParent(arguments);\r | |
324 | }\r | |
325 | });\r |