Roo/bootstrap/TabGroup.js
[roojs1] / Roo / bootstrap / TabGroup.js
1 /*
2  * - LGPL
3  *
4  * column
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.TabGroup
10  * @extends Roo.bootstrap.Column
11  * Bootstrap Column class
12  * @cfg {String} navId the navigation id (for use with navbars) - will be auto generated if it does not exist..
13  * @cfg {Boolean} carousel true to make the group behave like a carousel
14  * @cfg {Number} bullets show the panel pointer.. default 0
15  * @cfg {Boolean} autoslide (true|false) auto slide .. default false
16  * @cfg {Boolean} slideOnTouch (true|false) slide on touch .. default false
17  * @cfg {Number} timer auto slide timer .. default 0 millisecond
18  * 
19  * @constructor
20  * Create a new TabGroup
21  * @param {Object} config The config object
22  */
23
24 Roo.bootstrap.TabGroup = function(config){
25     Roo.bootstrap.TabGroup.superclass.constructor.call(this, config);
26     if (!this.navId) {
27         this.navId = Roo.id();
28     }
29     this.tabs = [];
30     Roo.bootstrap.TabGroup.register(this);
31     
32 };
33
34 Roo.extend(Roo.bootstrap.TabGroup, Roo.bootstrap.Column,  {
35     
36     carousel : false,
37     transition : false,
38     bullets : 0,
39     timer : 0,
40     autoslide : false,
41     slideFn : false,
42     slideOnTouch : false,
43     
44     getAutoCreate : function()
45     {
46         var cfg = Roo.apply({}, Roo.bootstrap.TabGroup.superclass.getAutoCreate.call(this));
47         
48         cfg.cls += ' tab-content';
49         
50         Roo.log('get auto create...............');
51         
52         if (this.carousel) {
53             cfg.cls += ' carousel slide';
54             
55             cfg.cn = [{
56                cls : 'carousel-inner'
57             }];
58         
59             if(this.bullets > 0 && !Roo.isTouch){
60                 
61                 var bullets = {
62                     cls : 'carousel-bullets',
63                     cn : []
64                 };
65                 
66                 if(this.bullets_cls){
67                     bullets.cls = bullets.cls + ' ' + this.bullets_cls;
68                 }
69                 
70                 for (var i = 0; i < this.bullets; i++){
71                     bullets.cn.push({
72                         cls : 'bullet bullet-' + i
73                     });
74                 }
75                 
76                 bullets.cn.push({
77                     cls : 'clear'
78                 });
79                 
80                 cfg.cn[0].cn = bullets;
81             }
82         }
83         
84         return cfg;
85     },
86     
87     initEvents:  function()
88     {
89         Roo.log('-------- init events on tab group ---------');
90         
91         if(this.bullets > 0 && !Roo.isTouch){
92             this.initBullet();
93         }
94         
95         Roo.log(this);
96         
97         if(Roo.isTouch){
98             this.el.on("touchstart", this.onTouchStart, this);
99         }
100         
101         if(this.autoslide){
102             var _this = this;
103             
104             this.slideFn = window.setInterval(function() {
105                 _this.showPanelNext();
106             }, this.timer);
107         }
108         
109     },
110     
111     onTouchStart : function(e, el, o)
112     {
113         if(!Roo.isTouch || Roo.get(e.getTarget()).hasClass('roo-button-text')){
114             return;
115         }
116         
117         this.showPanelNext();
118     },
119     
120     getChildContainer : function()
121     {
122         return this.carousel ? this.el.select('.carousel-inner', true).first() : this.el;
123     },
124     
125     /**
126     * register a Navigation item
127     * @param {Roo.bootstrap.NavItem} the navitem to add
128     */
129     register : function(item)
130     {
131         this.tabs.push( item);
132         item.navId = this.navId; // not really needed..
133     
134     },
135     
136     getActivePanel : function()
137     {
138         var r = false;
139         Roo.each(this.tabs, function(t) {
140             if (t.active) {
141                 r = t;
142                 return false;
143             }
144             return null;
145         });
146         return r;
147         
148     },
149     getPanelByName : function(n)
150     {
151         var r = false;
152         Roo.each(this.tabs, function(t) {
153             if (t.tabId == n) {
154                 r = t;
155                 return false;
156             }
157             return null;
158         });
159         return r;
160     },
161     indexOfPanel : function(p)
162     {
163         var r = false;
164         Roo.each(this.tabs, function(t,i) {
165             if (t.tabId == p.tabId) {
166                 r = i;
167                 return false;
168             }
169             return null;
170         });
171         return r;
172     },
173     /**
174      * show a specific panel
175      * @param {Roo.bootstrap.TabPanel|number|string} panel to change to (use the tabId to specify a specific one)
176      * @return {boolean} false if panel was not shown (invalid entry or beforedeactivate fails.)
177      */
178     showPanel : function (pan)
179     {
180         if(this.transition){
181             Roo.log("waiting for the transitionend");
182             return;
183         }
184         
185         if (typeof(pan) == 'number') {
186             pan = this.tabs[pan];
187         }
188         if (typeof(pan) == 'string') {
189             pan = this.getPanelByName(pan);
190         }
191         if (pan.tabId == this.getActivePanel().tabId) {
192             return true;
193         }
194         var cur = this.getActivePanel();
195         
196         if (false === cur.fireEvent('beforedeactivate')) {
197             return false;
198         }
199         
200         if(this.bullets > 0 && !Roo.isTouch){
201             this.setActiveBullet(this.indexOfPanel(pan));
202         }
203         
204         if (this.carousel && typeof(Roo.get(document.body).dom.style.transition) != 'undefined') {
205             
206             this.transition = true;
207             var dir = this.indexOfPanel(pan) > this.indexOfPanel(cur)  ? 'next' : 'prev';
208             var lr = dir == 'next' ? 'left' : 'right';
209             pan.el.addClass(dir); // or prev
210             pan.el.dom.offsetWidth; // find the offset with - causing a reflow?
211             cur.el.addClass(lr); // or right
212             pan.el.addClass(lr);
213             
214             var _this = this;
215             cur.el.on('transitionend', function() {
216                 Roo.log("trans end?");
217                 
218                 pan.el.removeClass([lr,dir]);
219                 pan.setActive(true);
220                 
221                 cur.el.removeClass([lr]);
222                 cur.setActive(false);
223                 
224                 _this.transition = false;
225                 
226             }, this, { single:  true } );
227             
228             return true;
229         }
230         
231         cur.setActive(false);
232         pan.setActive(true);
233         
234         return true;
235         
236     },
237     showPanelNext : function()
238     {
239         var i = this.indexOfPanel(this.getActivePanel());
240         
241         if (i >= this.tabs.length - 1 && !this.autoslide) {
242             return;
243         }
244         
245         if (i >= this.tabs.length - 1 && this.autoslide) {
246             i = -1;
247         }
248         
249         this.showPanel(this.tabs[i+1]);
250     },
251     
252     showPanelPrev : function()
253     {
254         var i = this.indexOfPanel(this.getActivePanel());
255         
256         if (i  < 1 && !this.autoslide) {
257             return;
258         }
259         
260         if (i < 1 && this.autoslide) {
261             i = this.tabs.length;
262         }
263         
264         this.showPanel(this.tabs[i-1]);
265     },
266     
267     initBullet : function()
268     {
269         if(Roo.isTouch){
270             return;
271         }
272         
273         var _this = this;
274         
275         for (var i = 0; i < this.bullets; i++){
276             var bullet = this.el.select('.bullet-' + i, true).first();
277
278             if(!bullet){
279                 continue;
280             }
281
282             bullet.on('click', (function(e, el, o, ii, t){
283
284                 e.preventDefault();
285
286                 _this.showPanel(ii);
287
288                 if(_this.autoslide && _this.slideFn){
289                     clearInterval(_this.slideFn);
290                     _this.slideFn = window.setInterval(function() {
291                         _this.showPanelNext();
292                     }, _this.timer);
293                 }
294
295             }).createDelegate(this, [i, bullet], true));
296         }
297     },
298     
299     setActiveBullet : function(i)
300     {
301         if(Roo.isTouch){
302             return;
303         }
304         
305         Roo.each(this.el.select('.bullet', true).elements, function(el){
306             el.removeClass('selected');
307         });
308
309         var bullet = this.el.select('.bullet-' + i, true).first();
310         
311         if(!bullet){
312             return;
313         }
314         
315         bullet.addClass('selected');
316     }
317     
318     
319   
320 });
321
322  
323
324  
325  
326 Roo.apply(Roo.bootstrap.TabGroup, {
327     
328     groups: {},
329      /**
330     * register a Navigation Group
331     * @param {Roo.bootstrap.NavGroup} the navgroup to add
332     */
333     register : function(navgrp)
334     {
335         this.groups[navgrp.navId] = navgrp;
336         
337     },
338     /**
339     * fetch a Navigation Group based on the navigation ID
340     * if one does not exist , it will get created.
341     * @param {string} the navgroup to add
342     * @returns {Roo.bootstrap.NavGroup} the navgroup 
343     */
344     get: function(navId) {
345         if (typeof(this.groups[navId]) == 'undefined') {
346             this.register(new Roo.bootstrap.TabGroup({ navId : navId }));
347         }
348         return this.groups[navId] ;
349     }
350     
351     
352     
353 });
354
355