better support for mailchimp emails
[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|light|dark) default none
14  * @cfg {Boolean} button_outline show and outlined button
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  * @cfg {String} linkcls  Link Class
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     linkcls : '',
83     navLink: false,
84     
85     getAutoCreate : function(){
86          
87         var cfg = {
88             tag: this.tag,
89             cls: 'nav-item'
90         };
91         
92         cfg.cls =  typeof(cfg.cls) == 'undefined'  ? '' : cfg.cls;
93         
94         if (this.active) {
95             cfg.cls +=  ' active' ;
96         }
97         if (this.disabled) {
98             cfg.cls += ' disabled';
99         }
100         
101         // BS4 only?
102         if (this.button_weight.length) {
103             cfg.tag = this.href ? 'a' : 'button';
104             cfg.html = this.html || '';
105             cfg.cls += ' btn btn' + (this.button_outline ? '-outline' : '') + '-' + this.button_weight;
106             if (this.href) {
107                 cfg.href = this.href;
108             }
109             if (this.fa) {
110                 cfg.html = '<i class="fa fas fa-'+this.fa+'"></i> <span class="nav-html">' + this.html + '</span>';
111             } else {
112                 cfg.cls += " nav-html";
113             }
114             
115             // menu .. should add dropdown-menu class - so no need for carat..
116             
117             if (this.badge !== '') {
118                  
119                 cfg.html += ' <span class="badge badge-secondary">' + this.badge + '</span>';
120             }
121             return cfg;
122         }
123         
124         if (this.href || this.html || this.glyphicon || this.icon || this.fa) {
125             cfg.cn = [
126                 {
127                     tag: this.tagtype,
128                     href : this.href || "#",
129                     html: this.html || '',
130                     cls : ''
131                 }
132             ];
133             if (this.tagtype == 'a') {
134                 cfg.cn[0].cls = 'nav-link' +  (this.active ?  ' active'  : '') + ' ' + this.linkcls;
135         
136             }
137             if (this.icon) {
138                 cfg.cn[0].html = '<i class="'+this.icon+'"></i> <span class="nav-html">' + cfg.cn[0].html + '</span>';
139             } else  if (this.fa) {
140                 cfg.cn[0].html = '<i class="fa fas fa-'+this.fa+'"></i> <span class="nav-html">' + cfg.cn[0].html + '</span>';
141             } else if(this.glyphicon) {
142                 cfg.cn[0].html = '<span class="glyphicon glyphicon-' + this.glyphicon + '"></span> '  + cfg.cn[0].html;
143             } else {
144                 cfg.cn[0].cls += " nav-html";
145             }
146             
147             if (this.menu) {
148                 cfg.cn[0].html += " <span class='caret'></span>";
149              
150             }
151             
152             if (this.badge !== '') {
153                 cfg.cn[0].html += ' <span class="badge badge-secondary">' + this.badge + '</span>';
154             }
155         }
156         
157         
158         
159         return cfg;
160     },
161     onRender : function(ct, position)
162     {
163        // Roo.log("Call onRender: " + this.xtype);
164         if (Roo.bootstrap.version == 4 && ct.dom.type != 'ul') {
165             this.tag = 'div';
166         }
167         
168         var ret = Roo.bootstrap.NavItem.superclass.onRender.call(this, ct, position);
169         this.navLink = this.el.select('.nav-link',true).first();
170         this.htmlEl = this.el.hasClass('nav-html') ? this.el : this.el.select('.nav-html',true).first();
171         return ret;
172     },
173       
174     
175     initEvents: function() 
176     {
177         if (typeof (this.menu) != 'undefined') {
178             this.menu.parentType = this.xtype;
179             this.menu.triggerEl = this.el;
180             this.menu = this.addxtype(Roo.apply({}, this.menu));
181         }
182         
183         this.el.on('click', this.onClick, this);
184         
185         //if(this.tagtype == 'span'){
186         //    this.el.select('span',true).on('click', this.onClick, this);
187         //}
188        
189         // at this point parent should be available..
190         this.parent().register(this);
191     },
192     
193     onClick : function(e)
194     {
195         if (e.getTarget('.dropdown-menu-item')) {
196             // did you click on a menu itemm.... - then don't trigger onclick..
197             return;
198         }
199         
200         if(
201                 this.preventDefault || 
202                 this.href == '#' 
203         ){
204             Roo.log("NavItem - prevent Default?");
205             e.preventDefault();
206         }
207         
208         if (this.disabled) {
209             return;
210         }
211         
212         var tg = Roo.bootstrap.TabGroup.get(this.navId);
213         if (tg && tg.transition) {
214             Roo.log("waiting for the transitionend");
215             return;
216         }
217         
218         
219         
220         //Roo.log("fire event clicked");
221         if(this.fireEvent('click', this, e) === false){
222             return;
223         };
224         
225         if(this.tagtype == 'span'){
226             return;
227         }
228         
229         //Roo.log(this.href);
230         var ael = this.el.select('a',true).first();
231         //Roo.log(ael);
232         
233         if(ael && this.animateRef && this.href.indexOf('#') > -1){
234             //Roo.log(["test:",ael.dom.href.split("#")[0], document.location.toString().split("#")[0]]);
235             if (ael.dom.href.split("#")[0] != document.location.toString().split("#")[0]) {
236                 return; // ignore... - it's a 'hash' to another page.
237             }
238             Roo.log("NavItem - prevent Default?");
239             e.preventDefault();
240             this.scrollToElement(e);
241         }
242         
243         
244         var p =  this.parent();
245    
246         if (['tabs','pills'].indexOf(p.type)!==-1 && p.pilltype) {
247             if (typeof(p.setActiveItem) !== 'undefined') {
248                 p.setActiveItem(this);
249             }
250         }
251         
252         // if parent is a navbarheader....- and link is probably a '#' page ref.. then remove the expanded menu.
253         if (p.parentType == 'NavHeaderbar' && !this.menu) {
254             // remove the collapsed menu expand...
255             p.parent().el.select('.roo-navbar-collapse',true).removeClass('in');  
256         }
257     },
258     
259     isActive: function () {
260         return this.active
261     },
262     setActive : function(state, fire, is_was_active)
263     {
264         if (this.active && !state && this.navId) {
265             this.was_active = true;
266             var nv = Roo.bootstrap.NavGroup.get(this.navId);
267             if (nv) {
268                 nv.clearWasActive(this);
269             }
270             
271         }
272         this.active = state;
273         
274         if (!state ) {
275             this.el.removeClass('active');
276             this.navLink ? this.navLink.removeClass('active') : false;
277         } else if (!this.el.hasClass('active')) {
278             
279             this.el.addClass('active');
280             if (Roo.bootstrap.version == 4 && this.navLink ) {
281                 this.navLink.addClass('active');
282             }
283             
284         }
285         if (fire) {
286             this.fireEvent('changed', this, state);
287         }
288         
289         // show a panel if it's registered and related..
290         
291         if (!this.navId || !this.tabId || !state || is_was_active) {
292             return;
293         }
294         
295         var tg = Roo.bootstrap.TabGroup.get(this.navId);
296         if (!tg) {
297             return;
298         }
299         var pan = tg.getPanelByName(this.tabId);
300         if (!pan) {
301             return;
302         }
303         // if we can not flip to new panel - go back to old nav highlight..
304         if (false == tg.showPanel(pan)) {
305             var nv = Roo.bootstrap.NavGroup.get(this.navId);
306             if (nv) {
307                 var onav = nv.getWasActive();
308                 if (onav) {
309                     onav.setActive(true, false, true);
310                 }
311             }
312             
313         }
314         
315         
316         
317     },
318      // this should not be here...
319     setDisabled : function(state)
320     {
321         this.disabled = state;
322         if (!state ) {
323             this.el.removeClass('disabled');
324         } else if (!this.el.hasClass('disabled')) {
325             this.el.addClass('disabled');
326         }
327         
328     },
329     
330     /**
331      * Fetch the element to display the tooltip on.
332      * @return {Roo.Element} defaults to this.el
333      */
334     tooltipEl : function()
335     {
336         return this.el; //this.tagtype  == 'a' ? this.el  : this.el.select('' + this.tagtype + '', true).first();
337     },
338     
339     scrollToElement : function(e)
340     {
341         var c = document.body;
342         
343         /*
344          * Firefox / IE places the overflow at the html level, unless specifically styled to behave differently.
345          */
346         if(Roo.isFirefox || Roo.isIE || Roo.isIE11){
347             c = document.documentElement;
348         }
349         
350         var target = Roo.get(c).select('a[name=' + this.href.split('#')[1] +']', true).first();
351         
352         if(!target){
353             return;
354         }
355
356         var o = target.calcOffsetsTo(c);
357         
358         var options = {
359             target : target,
360             value : o[1]
361         };
362         
363         this.fireEvent('scrollto', this, options, e);
364         
365         Roo.get(c).scrollTo('top', options.value, true);
366         
367         return;
368     },
369     /**
370      * Set the HTML (text content) of the item
371      * @param {string} html  content for the nav item
372      */
373     setHtml : function(html)
374     {
375         this.html = html;
376         this.htmlEl.dom.innerHTML = html;
377         
378     } 
379 });
380  
381
382