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