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