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