sync
[roojs1] / Roo / bootstrap / NavItem.js
1 /*
2  * - LGPL
3  *
4  * row
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.NavItem
10  * @extends Roo.bootstrap.Component
11  * Bootstrap Navbar.NavItem class
12  * @cfg {String} href  link to
13  * @cfg {String} html content of button
14  * @cfg {String} badge text inside badge
15  * @cfg {String} badgecls (bg-green|bg-red|bg-yellow)the extra classes for the badge
16  * @cfg {String} glyphicon name of glyphicon
17  * @cfg {String} icon name of font awesome icon
18  * @cfg {Boolean} active Is item active
19  * @cfg {Boolean} disabled Is item disabled
20  
21  * @cfg {Boolean} preventDefault (true | false) default false
22  * @cfg {String} tabId the tab that this item activates.
23  * @cfg {String} tagtype (a|span) render as a href or span?
24  * @cfg {Boolean} animateRef (true|false) link to element default false  
25   
26  * @constructor
27  * Create a new Navbar Item
28  * @param {Object} config The config object
29  */
30 Roo.bootstrap.NavItem = function(config){
31     Roo.bootstrap.NavItem.superclass.constructor.call(this, config);
32     this.addEvents({
33         // raw events
34         /**
35          * @event click
36          * The raw click event for the entire grid.
37          * @param {Roo.EventObject} e
38          */
39         "click" : true,
40          /**
41             * @event changed
42             * Fires when the active item active state changes
43             * @param {Roo.bootstrap.NavItem} this
44             * @param {boolean} state the new state
45              
46          */
47         'changed': true,
48         /**
49             * @event scrollto
50             * Fires when scroll to element
51             * @param {Roo.bootstrap.NavItem} this
52             * @param {Object} options
53             * @param {Roo.EventObject} e
54              
55          */
56         'scrollto': true
57     });
58    
59 };
60
61 Roo.extend(Roo.bootstrap.NavItem, Roo.bootstrap.Component,  {
62     
63     href: false,
64     html: '',
65     badge: '',
66     icon: false,
67     glyphicon: false,
68     active: false,
69     preventDefault : false,
70     tabId : false,
71     tagtype : 'a',
72     disabled : false,
73     animateRef : false,
74     was_active : false,
75     
76     getAutoCreate : function(){
77          
78         var cfg = {
79             tag: 'li',
80             cls: 'nav-item'
81             
82         };
83         
84         if (this.active) {
85             cfg.cls = typeof(cfg.cls) == 'undefined' ? 'active' : cfg.cls + ' active';
86         }
87         if (this.disabled) {
88             cfg.cls += ' disabled';
89         }
90         
91         if (this.href || this.html || this.glyphicon || this.icon) {
92             cfg.cn = [
93                 {
94                     tag: this.tagtype,
95                     href : this.href || "#",
96                     html: this.html || ''
97                 }
98             ];
99             
100             if (this.icon) {
101                 cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span>' + cfg.cn[0].html + '</span>'
102             }
103
104             if(this.glyphicon) {
105                 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span> '  + cfg.cn[0].html;
106             }
107             
108             if (this.menu) {
109                 
110                 cfg.cn[0].html += " <span class='caret'></span>";
111              
112             }
113             
114             if (this.badge !== '') {
115                  
116                 cfg.cn[0].html += ' <span class="badge">' + this.badge + '</span>';
117             }
118         }
119         
120         
121         
122         return cfg;
123     },
124     initEvents: function() 
125     {
126         if (typeof (this.menu) != 'undefined') {
127             this.menu.parentType = this.xtype;
128             this.menu.triggerEl = this.el;
129             this.menu = this.addxtype(Roo.apply({}, this.menu));
130         }
131         
132         this.el.select('a',true).on('click', this.onClick, this);
133         
134         if(this.tagtype == 'span'){
135             this.el.select('span',true).on('click', this.onClick, this);
136         }
137        
138         // at this point parent should be available..
139         this.parent().register(this);
140     },
141     
142     onClick : function(e)
143     {
144         if (e.getTarget('.dropdown-menu-item')) {
145             // did you click on a menu itemm.... - then don't trigger onclick..
146             return;
147         }
148         
149         if(
150                 this.preventDefault || 
151                 this.href == '#' 
152         ){
153             Roo.log("NavItem - prevent Default?");
154             e.preventDefault();
155         }
156         
157         if (this.disabled) {
158             return;
159         }
160         
161         var tg = Roo.bootstrap.TabGroup.get(this.navId);
162         if (tg && tg.transition) {
163             Roo.log("waiting for the transitionend");
164             return;
165         }
166         
167         
168         
169         //Roo.log("fire event clicked");
170         if(this.fireEvent('click', this, e) === false){
171             return;
172         };
173         
174         if(this.tagtype == 'span'){
175             return;
176         }
177         
178         //Roo.log(this.href);
179         var ael = this.el.select('a',true).first();
180         //Roo.log(ael);
181         
182         if(ael && this.animateRef && this.href.indexOf('#') > -1){
183             //Roo.log(["test:",ael.dom.href.split("#")[0], document.location.toString().split("#")[0]]);
184             if (ael.dom.href.split("#")[0] != document.location.toString().split("#")[0]) {
185                 return; // ignore... - it's a 'hash' to another page.
186             }
187             Roo.log("NavItem - prevent Default?");
188             e.preventDefault();
189             this.scrollToElement(e);
190         }
191         
192         
193         var p =  this.parent();
194    
195         if (['tabs','pills'].indexOf(p.type)!==-1) {
196             if (typeof(p.setActiveItem) !== 'undefined') {
197                 p.setActiveItem(this);
198             }
199         }
200         
201         // if parent is a navbarheader....- and link is probably a '#' page ref.. then remove the expanded menu.
202         if (p.parentType == 'NavHeaderbar' && !this.menu) {
203             // remove the collapsed menu expand...
204             p.parent().el.select('.navbar-collapse',true).removeClass('in');  
205         }
206     },
207     
208     isActive: function () {
209         return this.active
210     },
211     setActive : function(state, fire, is_was_active)
212     {
213         if (this.active && !state && this.navId) {
214             this.was_active = true;
215             var nv = Roo.bootstrap.NavGroup.get(this.navId);
216             if (nv) {
217                 nv.clearWasActive(this);
218             }
219             
220         }
221         this.active = state;
222         
223         if (!state ) {
224             this.el.removeClass('active');
225         } else if (!this.el.hasClass('active')) {
226             this.el.addClass('active');
227         }
228         if (fire) {
229             this.fireEvent('changed', this, state);
230         }
231         
232         // show a panel if it's registered and related..
233         
234         if (!this.navId || !this.tabId || !state || is_was_active) {
235             return;
236         }
237         
238         var tg = Roo.bootstrap.TabGroup.get(this.navId);
239         if (!tg) {
240             return;
241         }
242         var pan = tg.getPanelByName(this.tabId);
243         if (!pan) {
244             return;
245         }
246         // if we can not flip to new panel - go back to old nav highlight..
247         if (false == tg.showPanel(pan)) {
248             var nv = Roo.bootstrap.NavGroup.get(this.navId);
249             if (nv) {
250                 var onav = nv.getWasActive();
251                 if (onav) {
252                     onav.setActive(true, false, true);
253                 }
254             }
255             
256         }
257         
258         
259         
260     },
261      // this should not be here...
262     setDisabled : function(state)
263     {
264         this.disabled = state;
265         if (!state ) {
266             this.el.removeClass('disabled');
267         } else if (!this.el.hasClass('disabled')) {
268             this.el.addClass('disabled');
269         }
270         
271     },
272     
273     /**
274      * Fetch the element to display the tooltip on.
275      * @return {Roo.Element} defaults to this.el
276      */
277     tooltipEl : function()
278     {
279         return this.el.select('' + this.tagtype + '', true).first();
280     },
281     
282     scrollToElement : function(e)
283     {
284         var c = document.body;
285         
286         /*
287          * Firefox / IE places the overflow at the html level, unless specifically styled to behave differently.
288          */
289         if(Roo.isFirefox || Roo.isIE || Roo.isIE11){
290             c = document.documentElement;
291         }
292         
293         var target = Roo.get(c).select('a[name=' + this.href.split('#')[1] +']', true).first();
294         
295         if(!target){
296             return;
297         }
298
299         var o = target.calcOffsetsTo(c);
300         
301         var options = {
302             target : target,
303             value : o[1]
304         };
305         
306         this.fireEvent('scrollto', this, options, e);
307         
308         Roo.get(c).scrollTo('top', options.value, true);
309         
310         return;
311     }
312 });
313  
314
315