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 {Boolean} bullets show bullets for the panels
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         Roo.log(cfg);
49         
50         cfg.cls += ' tab-content';
51         
52         if (this.carousel) {
53             cfg.cls += ' carousel slide';
54             
55             cfg.cn = [{
56                cls : 'carousel-inner'
57             }];
58         
59             if(this.bullets  && !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             cfg.cn.push({
84                 tag : 'div',
85                 class : 'carousel-nav',
86                 cn : [
87                     {
88                         tag : 'div',
89                         class : 'carousel-prev',
90                         cn : [
91                             {
92                                 tag : 'i',
93                                 class : 'fa fa-chevron-left'
94                             }
95                         ]
96                     },
97                     {
98                         tag : 'div',
99                         class : 'carousel-next',
100                         cn : [
101                             {
102                                 tag : 'i',
103                                 class : 'fa fa-chevron-right'
104                             }
105                         ]
106                     }
107                 ]
108             });
109         }
110         
111         return cfg;
112     },
113     
114     initEvents:  function()
115     {
116         if(Roo.isTouch && this.slideOnTouch){
117             this.el.on("touchstart", this.onTouchStart, this);
118         }
119         
120         if(this.autoslide){
121             var _this = this;
122             
123             this.slideFn = window.setInterval(function() {
124                 _this.showPanelNext();
125             }, this.timer);
126         }
127         
128     },
129     
130     onTouchStart : function(e, el, o)
131     {
132         if(!this.slideOnTouch || !Roo.isTouch || Roo.get(e.getTarget()).hasClass('roo-button-text')){
133             return;
134         }
135         
136         this.showPanelNext();
137     },
138     
139     getChildContainer : function()
140     {
141         return this.carousel ? this.el.select('.carousel-inner', true).first() : this.el;
142     },
143     
144     /**
145     * register a Navigation item
146     * @param {Roo.bootstrap.NavItem} the navitem to add
147     */
148     register : function(item)
149     {
150         this.tabs.push( item);
151         item.navId = this.navId; // not really needed..
152         this.addBullet();
153     
154     },
155     
156     getActivePanel : function()
157     {
158         var r = false;
159         Roo.each(this.tabs, function(t) {
160             if (t.active) {
161                 r = t;
162                 return false;
163             }
164             return null;
165         });
166         return r;
167         
168     },
169     getPanelByName : function(n)
170     {
171         var r = false;
172         Roo.each(this.tabs, function(t) {
173             if (t.tabId == n) {
174                 r = t;
175                 return false;
176             }
177             return null;
178         });
179         return r;
180     },
181     indexOfPanel : function(p)
182     {
183         var r = false;
184         Roo.each(this.tabs, function(t,i) {
185             if (t.tabId == p.tabId) {
186                 r = i;
187                 return false;
188             }
189             return null;
190         });
191         return r;
192     },
193     /**
194      * show a specific panel
195      * @param {Roo.bootstrap.TabPanel|number|string} panel to change to (use the tabId to specify a specific one)
196      * @return {boolean} false if panel was not shown (invalid entry or beforedeactivate fails.)
197      */
198     showPanel : function (pan)
199     {
200         if(this.transition || typeof(pan) == 'undefined'){
201             Roo.log("waiting for the transitionend");
202             return;
203         }
204         
205         if (typeof(pan) == 'number') {
206             pan = this.tabs[pan];
207         }
208         
209         if (typeof(pan) == 'string') {
210             pan = this.getPanelByName(pan);
211         }
212         
213         var cur = this.getActivePanel();
214         
215         if(!pan || !cur){
216             Roo.log('pan or acitve pan is undefined');
217             return false;
218         }
219         
220         if (pan.tabId == this.getActivePanel().tabId) {
221             return true;
222         }
223         
224         if (false === cur.fireEvent('beforedeactivate')) {
225             return false;
226         }
227         
228         if(this.bullets > 0 && !Roo.isTouch){
229             this.setActiveBullet(this.indexOfPanel(pan));
230         }
231         
232         if (this.carousel && typeof(Roo.get(document.body).dom.style.transition) != 'undefined') {
233             
234             this.transition = true;
235             var dir = this.indexOfPanel(pan) > this.indexOfPanel(cur)  ? 'next' : 'prev';
236             var lr = dir == 'next' ? 'left' : 'right';
237             pan.el.addClass(dir); // or prev
238             pan.el.dom.offsetWidth; // find the offset with - causing a reflow?
239             cur.el.addClass(lr); // or right
240             pan.el.addClass(lr);
241             
242             var _this = this;
243             cur.el.on('transitionend', function() {
244                 Roo.log("trans end?");
245                 
246                 pan.el.removeClass([lr,dir]);
247                 pan.setActive(true);
248                 
249                 cur.el.removeClass([lr]);
250                 cur.setActive(false);
251                 
252                 _this.transition = false;
253                 
254             }, this, { single:  true } );
255             
256             return true;
257         }
258         
259         cur.setActive(false);
260         pan.setActive(true);
261         
262         return true;
263         
264     },
265     showPanelNext : function()
266     {
267         var i = this.indexOfPanel(this.getActivePanel());
268         
269         if (i >= this.tabs.length - 1 && !this.autoslide) {
270             return;
271         }
272         
273         if (i >= this.tabs.length - 1 && this.autoslide) {
274             i = -1;
275         }
276         
277         this.showPanel(this.tabs[i+1]);
278     },
279     
280     showPanelPrev : function()
281     {
282         var i = this.indexOfPanel(this.getActivePanel());
283         
284         if (i  < 1 && !this.autoslide) {
285             return;
286         }
287         
288         if (i < 1 && this.autoslide) {
289             i = this.tabs.length;
290         }
291         
292         this.showPanel(this.tabs[i-1]);
293     },
294     
295     
296     addBullet: function()
297     {
298         if(!this.bullets || Roo.isTouch){
299             return;
300         }
301         var ctr = this.el.select('.carousel-bullets',true).first();
302         var i = this.el.select('.carousel-bullets .bullet',true).getCount() ;
303         var bullet = ctr.createChild({
304             cls : 'bullet bullet-' + i
305         },ctr.dom.lastChild);
306         
307         
308         var _this = this;
309         
310         bullet.on('click', (function(e, el, o, ii, t){
311
312             e.preventDefault();
313
314             this.showPanel(ii);
315
316             if(this.autoslide && this.slideFn){
317                 clearInterval(this.slideFn);
318                 this.slideFn = window.setInterval(function() {
319                     _this.showPanelNext();
320                 }, this.timer);
321             }
322
323         }).createDelegate(this, [i, bullet], true));
324                 
325         
326     },
327      
328     setActiveBullet : function(i)
329     {
330         if(Roo.isTouch){
331             return;
332         }
333         
334         Roo.each(this.el.select('.bullet', true).elements, function(el){
335             el.removeClass('selected');
336         });
337
338         var bullet = this.el.select('.bullet-' + i, true).first();
339         
340         if(!bullet){
341             return;
342         }
343         
344         bullet.addClass('selected');
345     }
346     
347     
348   
349 });
350
351  
352
353  
354  
355 Roo.apply(Roo.bootstrap.TabGroup, {
356     
357     groups: {},
358      /**
359     * register a Navigation Group
360     * @param {Roo.bootstrap.NavGroup} the navgroup to add
361     */
362     register : function(navgrp)
363     {
364         this.groups[navgrp.navId] = navgrp;
365         
366     },
367     /**
368     * fetch a Navigation Group based on the navigation ID
369     * if one does not exist , it will get created.
370     * @param {string} the navgroup to add
371     * @returns {Roo.bootstrap.NavGroup} the navgroup 
372     */
373     get: function(navId) {
374         if (typeof(this.groups[navId]) == 'undefined') {
375             this.register(new Roo.bootstrap.TabGroup({ navId : navId }));
376         }
377         return this.groups[navId] ;
378     }
379     
380     
381     
382 });
383
384