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