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