Roo/bootstrap/Button.js
[roojs1] / Roo / bootstrap / Button.js
1 /*
2  * - LGPL
3  *
4  * button
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.Button
10  * @extends Roo.bootstrap.Component
11  * Bootstrap Button class
12  * @cfg {String} html The button content
13  * @cfg {String} weight (default | primary | secondary | success | info | warning | danger | link ) default
14  * @cfg {String} badge_weight (default | primary | secondary | success | info | warning | danger | link ) default (same as button)
15  * @cfg {Boolean} outline default false (except for weight=default which emulates old behaveiour with an outline)
16  * @cfg {String} size ( lg | sm | xs)
17  * @cfg {String} tag ( a | input | submit)
18  * @cfg {String} href empty or href
19  * @cfg {Boolean} disabled default false;
20  * @cfg {Boolean} isClose default false;
21  * @cfg {String} glyphicon depricated - use fs
22  * @cfg {String} badge text for badge
23  * @cfg {String} theme (default|glow)  
24  * @cfg {Boolean} inverse dark themed version
25  * @cfg {Boolean} toggle is it a slidy toggle button
26  * @cfg {Boolean} pressed (true|false) default null - if the button ahs active state
27  * @cfg {String} ontext text for on slidy toggle state
28  * @cfg {String} offtext text for off slidy toggle state
29  * @cfg {Boolean} preventDefault  default true (stop click event triggering the URL if it's a link.)
30  * @cfg {Boolean} removeClass remove the standard class..
31  * @cfg {String} target  target for a href. (_self|_blank|_parent|_top| other)
32  * 
33  * @constructor
34  * Create a new button
35  * @param {Object} config The config object
36  */
37
38
39 Roo.bootstrap.Button = function(config){
40     Roo.bootstrap.Button.superclass.constructor.call(this, config);
41     this.weightClass = ["btn-default btn-outline-secondary", 
42                        "btn-primary", 
43                        "btn-success", 
44                        "btn-info", 
45                        "btn-warning",
46                        "btn-danger",
47                        "btn-link"
48                       ],  
49     this.addEvents({
50         // raw events
51         /**
52          * @event click
53          * When a butotn is pressed
54          * @param {Roo.bootstrap.Button} btn
55          * @param {Roo.EventObject} e
56          */
57         "click" : true,
58          /**
59          * @event toggle
60          * After the button has been toggles
61          * @param {Roo.bootstrap.Button} btn
62          * @param {Roo.EventObject} e
63          * @param {boolean} pressed (also available as button.pressed)
64          */
65         "toggle" : true
66     });
67 };
68
69 Roo.extend(Roo.bootstrap.Button, Roo.bootstrap.Component,  {
70     html: false,
71     active: false,
72     weight: '',
73     badge_weight: '',
74     outline : false,
75     size: '',
76     tag: 'button',
77     href: '',
78     disabled: false,
79     isClose: false,
80     glyphicon: '',
81     fa: '',
82     badge: '',
83     theme: 'default',
84     inverse: false,
85     
86     toggle: false,
87     ontext: 'ON',
88     offtext: 'OFF',
89     defaulton: true,
90     preventDefault: true,
91     removeClass: false,
92     name: false,
93     target: false,
94      
95     pressed : null,
96      
97     
98     getAutoCreate : function(){
99         
100         var cfg = {
101             tag : 'button',
102             cls : 'roo-button',
103             html: ''
104         };
105         
106         if (['a', 'button', 'input', 'submit'].indexOf(this.tag) < 0) {
107             throw "Invalid value for tag: " + this.tag + ". must be a, button, input or submit.";
108             this.tag = 'button';
109         } else {
110             cfg.tag = this.tag;
111         }
112         cfg.html = '<span class="roo-button-text">' + (this.html || cfg.html) + '</span>';
113         
114         if (this.toggle == true) {
115             cfg={
116                 tag: 'div',
117                 cls: 'slider-frame roo-button',
118                 cn: [
119                     {
120                         tag: 'span',
121                         'data-on-text':'ON',
122                         'data-off-text':'OFF',
123                         cls: 'slider-button',
124                         html: this.offtext
125                     }
126                 ]
127             };
128             
129             if (['default', 'secondary' , 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
130                 cfg.cls += ' '+this.weight;
131             }
132             
133             return cfg;
134         }
135         
136         if (this.isClose) {
137             cfg.cls += ' close';
138             
139             cfg["aria-hidden"] = true;
140             
141             cfg.html = "&times;";
142             
143             return cfg;
144         }
145         
146          
147         if (this.theme==='default') {
148             cfg.cls = 'btn roo-button';
149             
150             //if (this.parentType != 'Navbar') {
151             this.weight = this.weight.length ?  this.weight : 'default';
152             //}
153             if (['default', 'primary', 'secondary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
154                 
155                 var outline = this.outline || this.weight == 'default' ? 'outline-' : '';
156                 var weight = this.weight == 'default' ? 'secondary' : this.weight;
157                 cfg.cls += ' btn-' + outline + weight;
158                 if (this.weight == 'default') {
159                     // BC
160                     cfg.cls += ' btn-' + this.weight;
161                 }
162             }
163         } else if (this.theme==='glow') {
164             
165             cfg.tag = 'a';
166             cfg.cls = 'btn-glow roo-button';
167             
168             if (['default', 'primary', 'success', 'info', 'warning', 'danger', 'link'].indexOf(this.weight) > -1) {
169                 
170                 cfg.cls += ' ' + this.weight;
171             }
172         }
173    
174         
175         if (this.inverse) {
176             this.cls += ' inverse';
177         }
178         
179         
180         if (this.active || this.pressed === true) {
181             cfg.cls += ' active';
182         }
183         
184         if (this.disabled) {
185             cfg.disabled = 'disabled';
186         }
187         
188         if (this.items) {
189             Roo.log('changing to ul' );
190             cfg.tag = 'ul';
191             this.glyphicon = 'caret';
192             if (Roo.bootstrap.version == 4) {
193                 this.fa = 'caret-down';
194             }
195             
196         }
197         
198         cfg.cls += this.size.length ? (' btn-' + this.size) : '';
199          
200         //gsRoo.log(this.parentType);
201         if (this.parentType === 'Navbar' && !this.parent().bar) {
202             Roo.log('changing to li?');
203             
204             cfg.tag = 'li';
205             
206             cfg.cls = '';
207             cfg.cn =  [{
208                 tag : 'a',
209                 cls : 'roo-button',
210                 html : this.html,
211                 href : this.href || '#'
212             }];
213             if (this.menu) {
214                 cfg.cn[0].html = this.html  + ' <span class="caret"></span>';
215                 cfg.cls += ' dropdown';
216             }   
217             
218             delete cfg.html;
219             
220         }
221         
222        cfg.cls += this.parentType === 'Navbar' ?  ' navbar-btn' : '';
223         
224         if (this.glyphicon) {
225             cfg.html = ' ' + cfg.html;
226             
227             cfg.cn = [
228                 {
229                     tag: 'span',
230                     cls: 'glyphicon glyphicon-' + this.glyphicon
231                 }
232             ];
233         }
234         if (this.fa) {
235             cfg.html = ' ' + cfg.html;
236             
237             cfg.cn = [
238                 {
239                     tag: 'i',
240                     cls: 'fa fas fa-' + this.fa
241                 }
242             ];
243         }
244         
245         if (this.badge) {
246             cfg.html += ' ';
247             
248             cfg.tag = 'a';
249             
250 //            cfg.cls='btn roo-button';
251             
252             cfg.href=this.href;
253             
254             var value = cfg.html;
255             
256             if(this.glyphicon){
257                 value = {
258                     tag: 'span',
259                     cls: 'glyphicon glyphicon-' + this.glyphicon,
260                     html: this.html
261                 };
262             }
263             if(this.fa){
264                 value = {
265                     tag: 'i',
266                     cls: 'fa fas fa-' + this.fa,
267                     html: this.html
268                 };
269             }
270             
271             var bw = this.badge_weight.length ? this.badge_weight :
272                 (this.weight.length ? this.weight : 'secondary');
273             bw = bw == 'default' ? 'secondary' : bw;
274             
275             cfg.cn = [
276                 value,
277                 {
278                     tag: 'span',
279                     cls: 'badge badge-' + bw,
280                     html: this.badge
281                 }
282             ];
283             
284             cfg.html='';
285         }
286         
287         if (this.menu) {
288             cfg.cls += ' dropdown';
289             cfg.html = typeof(cfg.html) != 'undefined' ?
290                     cfg.html + ' <span class="caret"></span>' : '<span class="caret"></span>';
291         }
292         
293         if (cfg.tag !== 'a' && this.href !== '') {
294             throw "Tag must be a to set href.";
295         } else if (this.href.length > 0) {
296             cfg.href = this.href;
297         }
298         
299         if(this.removeClass){
300             cfg.cls = '';
301         }
302         
303         if(this.target){
304             cfg.target = this.target;
305         }
306         
307         return cfg;
308     },
309     initEvents: function() {
310        // Roo.log('init events?');
311 //        Roo.log(this.el.dom);
312         // add the menu...
313         
314         if (typeof (this.menu) != 'undefined') {
315             this.menu.parentType = this.xtype;
316             this.menu.triggerEl = this.el;
317             this.addxtype(Roo.apply({}, this.menu));
318         }
319
320
321        if (this.el.hasClass('roo-button')) {
322             this.el.on('click', this.onClick, this);
323        } else {
324             this.el.select('.roo-button').on('click', this.onClick, this);
325        }
326        
327        if(this.removeClass){
328            this.el.on('click', this.onClick, this);
329        }
330        
331        this.el.enableDisplayMode();
332         
333     },
334     onClick : function(e)
335     {
336         if (this.disabled) {
337             return;
338         }
339         
340         Roo.log('button on click ');
341         if(this.preventDefault){
342             e.preventDefault();
343         }
344         
345         if (this.pressed === true || this.pressed === false) {
346             this.toggleActive(e);
347         }
348         
349         
350         this.fireEvent('click', this, e);
351     },
352     
353     /**
354      * Enables this button
355      */
356     enable : function()
357     {
358         this.disabled = false;
359         this.el.removeClass('disabled');
360     },
361     
362     /**
363      * Disable this button
364      */
365     disable : function()
366     {
367         this.disabled = true;
368         this.el.addClass('disabled');
369     },
370      /**
371      * sets the active state on/off, 
372      * @param {Boolean} state (optional) Force a particular state
373      */
374     setActive : function(v) {
375         
376         this.el[v ? 'addClass' : 'removeClass']('active');
377         this.pressed = v;
378     },
379      /**
380      * toggles the current active state 
381      */
382     toggleActive : function(e)
383     {
384         this.setActive(!this.pressed);
385         this.fireEvent('toggle', this, e, !this.pressed);
386     },
387      /**
388      * get the current active state
389      * @return {boolean} true if it's active
390      */
391     isActive : function()
392     {
393         return this.el.hasClass('active');
394     },
395     /**
396      * set the text of the first selected button
397      */
398     setText : function(str)
399     {
400         this.el.select('.roo-button-text',true).first().dom.innerHTML = str;
401     },
402     /**
403      * get the text of the first selected button
404      */
405     getText : function()
406     {
407         return this.el.select('.roo-button-text',true).first().dom.innerHTML;
408     },
409     
410     setWeight : function(str)
411     {
412         this.el.removeClass(this.weightClass);
413         this.weight = str;
414         var outline = this.outline ? 'outline-' : '';
415         if (str == 'default') {
416             this.el.addClass('btn-default btn-outline-secondary');        
417             return;
418         }
419         this.el.addClass('btn-' + outline + str);        
420     }
421     
422     
423 });
424
425