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