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