Roo/bootstrap/TabPanel.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         if (this.carousel) {
51             cfg.cls += ' carousel slide';
52             
53             cfg.cn = [{
54                cls : 'carousel-inner'
55             }];
56         
57             if(this.bullets  && !Roo.isTouch){
58                 
59                 var bullets = {
60                     cls : 'carousel-bullets',
61                     cn : []
62                 };
63                
64                 if(this.bullets_cls){
65                     bullets.cls = bullets.cls + ' ' + this.bullets_cls;
66                 }
67                  /*
68                 for (var i = 0; i < this.bullets; i++){
69                     bullets.cn.push({
70                         cls : 'bullet bullet-' + i
71                     });
72                 }
73                 */
74                 bullets.cn.push({
75                     cls : 'clear'
76                 });
77                 
78                 cfg.cn[0].cn = bullets;
79             }
80         }
81         
82         return cfg;
83     },
84     
85     initEvents:  function()
86     {
87         if(Roo.isTouch && this.slideOnTouch){
88             this.el.on("touchstart", this.onTouchStart, this);
89         }
90         
91         if(this.autoslide){
92             var _this = this;
93             
94             this.slideFn = window.setInterval(function() {
95                 _this.showPanelNext();
96             }, this.timer);
97         }
98         
99     },
100     
101     onTouchStart : function(e, el, o)
102     {
103         if(!this.slideOnTouch || !Roo.isTouch || Roo.get(e.getTarget()).hasClass('roo-button-text')){
104             return;
105         }
106         
107         this.showPanelNext();
108     },
109     
110     getChildContainer : function()
111     {
112         return this.carousel ? this.el.select('.carousel-inner', true).first() : this.el;
113     },
114     
115     /**
116     * register a Navigation item
117     * @param {Roo.bootstrap.NavItem} the navitem to add
118     */
119     register : function(item)
120     {
121         this.tabs.push( item);
122         item.navId = this.navId; // not really needed..
123         this.addBullet();
124     
125     },
126     
127     getActivePanel : function()
128     {
129         var r = false;
130         Roo.each(this.tabs, function(t) {
131             if (t.active) {
132                 r = t;
133                 return false;
134             }
135             return null;
136         });
137         return r;
138         
139     },
140     getPanelByName : function(n)
141     {
142         var r = false;
143         Roo.each(this.tabs, function(t) {
144             if (t.tabId == n) {
145                 r = t;
146                 return false;
147             }
148             return null;
149         });
150         return r;
151     },
152     indexOfPanel : function(p)
153     {
154         var r = false;
155         Roo.each(this.tabs, function(t,i) {
156             if (t.tabId == p.tabId) {
157                 r = i;
158                 return false;
159             }
160             return null;
161         });
162         return r;
163     },
164     /**
165      * show a specific panel
166      * @param {Roo.bootstrap.TabPanel|number|string} panel to change to (use the tabId to specify a specific one)
167      * @return {boolean} false if panel was not shown (invalid entry or beforedeactivate fails.)
168      */
169     showPanel : function (pan)
170     {
171         if(this.transition || typeof(pan) == 'undefined'){
172             Roo.log("waiting for the transitionend");
173             return;
174         }
175         
176         if (typeof(pan) == 'number') {
177             pan = this.tabs[pan];
178         }
179         
180         if (typeof(pan) == 'string') {
181             pan = this.getPanelByName(pan);
182         }
183         
184         var cur = this.getActivePanel();
185         
186         if(!pan || !cur){
187             Roo.log('pan or acitve pan is undefined');
188             return false;
189         }
190         
191         if (pan.tabId == this.getActivePanel().tabId) {
192             return true;
193         }
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).getCount() ;
274         var bullet = ctr.createChild({
275             cls : 'bullet bullet-' + i
276         },ctr.dom.lastChild);
277         
278         
279         var _this = this;
280         
281         bullet.on('click', (function(e, el, o, ii, t){
282
283             e.preventDefault();
284
285             this.showPanel(ii);
286
287             if(this.autoslide && this.slideFn){
288                 clearInterval(this.slideFn);
289                 this.slideFn = window.setInterval(function() {
290                     _this.showPanelNext();
291                 }, this.timer);
292             }
293
294         }).createDelegate(this, [i, bullet], true));
295                 
296         
297     },
298      
299     setActiveBullet : function(i)
300     {
301         if(Roo.isTouch){
302             return;
303         }
304         
305         Roo.each(this.el.select('.bullet', true).elements, function(el){
306             el.removeClass('selected');
307         });
308
309         var bullet = this.el.select('.bullet-' + i, true).first();
310         
311         if(!bullet){
312             return;
313         }
314         
315         bullet.addClass('selected');
316     }
317     
318     
319   
320 });
321
322  
323
324  
325  
326 Roo.apply(Roo.bootstrap.TabGroup, {
327     
328     groups: {},
329      /**
330     * register a Navigation Group
331     * @param {Roo.bootstrap.NavGroup} the navgroup to add
332     */
333     register : function(navgrp)
334     {
335         this.groups[navgrp.navId] = navgrp;
336         
337     },
338     /**
339     * fetch a Navigation Group based on the navigation ID
340     * if one does not exist , it will get created.
341     * @param {string} the navgroup to add
342     * @returns {Roo.bootstrap.NavGroup} the navgroup 
343     */
344     get: function(navId) {
345         if (typeof(this.groups[navId]) == 'undefined') {
346             this.register(new Roo.bootstrap.TabGroup({ navId : navId }));
347         }
348         return this.groups[navId] ;
349     }
350     
351     
352     
353 });
354
355