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