8fc536b42f52e7225830bf01b11dead65630de50
[roojs1] / Roo / bootstrap / CheckBox.js
1 /*
2  * - LGPL
3  *
4  * CheckBox
5  * 
6  */
7
8 /**
9  * @class Roo.bootstrap.CheckBox
10  * @extends Roo.bootstrap.Input
11  * Bootstrap CheckBox class
12  * 
13  * @cfg {String} valueOff The value that should go into the generated input element's value when unchecked.
14  * @cfg {String} inputValue The value that should go into the generated input element's value when checked.
15  * @cfg {String} boxLabel The text that appears beside the checkbox
16  * @cfg {String} weight (primary|warning|info|danger|success) The text that appears beside the checkbox
17  * @cfg {Boolean} checked initnal the element
18  * @cfg {Boolean} inline inline the element (default false)
19  * @cfg {String} groupId the checkbox group id // normal just use for checkbox
20  * @cfg {String} tooltip label tooltip
21  * 
22  * @constructor
23  * Create a new CheckBox
24  * @param {Object} config The config object
25  */
26
27 Roo.bootstrap.CheckBox = function(config){
28     Roo.bootstrap.CheckBox.superclass.constructor.call(this, config);
29    
30     this.addEvents({
31         /**
32         * @event check
33         * Fires when the element is checked or unchecked.
34         * @param {Roo.bootstrap.CheckBox} this This input
35         * @param {Boolean} checked The new checked value
36         */
37        check : true,
38        /**
39         * @event click
40         * Fires when the element is click.
41         * @param {Roo.bootstrap.CheckBox} this This input
42         */
43        click : true
44     });
45     
46 };
47
48 Roo.extend(Roo.bootstrap.CheckBox, Roo.bootstrap.Input,  {
49   
50     inputType: 'checkbox',
51     inputValue: 1,
52     valueOff: 0,
53     boxLabel: false,
54     checked: false,
55     weight : false,
56     inline: false,
57     tooltip : '',
58     useFontAwesome : false,
59     
60     getAutoCreate : function()
61     {
62         var align = (!this.labelAlign) ? this.parentLabelAlign() : this.labelAlign;
63         
64         var id = Roo.id();
65         
66         var cfg = {};
67         
68         cfg.cls = 'form-group ' + this.inputType; //input-group
69         
70         if(this.inline){
71             cfg.cls += ' ' + this.inputType + '-inline';
72         }
73         
74         var input =  {
75             tag: 'input',
76             id : id,
77             type : this.inputType,
78             value : this.inputValue,
79             cls : 'roo-' + this.inputType, //'form-box',
80             placeholder : this.placeholder || ''
81             
82         };
83         
84         if(this.inputType != 'radio'){
85             var hidden =  {
86                 tag: 'input',
87                 type : 'hidden',
88                 cls : 'roo-hidden-value',
89                 value : this.checked ? this.inputValue : this.valueOff
90             };
91         }
92         
93             
94         if (this.weight) { // Validity check?
95             cfg.cls += " " + this.inputType + "-" + this.weight;
96         }
97         
98         if (this.disabled) {
99             input.disabled=true;
100         }
101         
102         if(this.checked){
103             input.checked = this.checked;
104         }
105         
106         if (this.name) {
107             
108             input.name = this.name;
109             
110             if(this.inputType != 'radio'){
111                 hidden.name = this.name;
112                 input.name = '_hidden_' + this.name;
113             }
114         }
115         
116         if (this.size) {
117             input.cls += ' input-' + this.size;
118         }
119         
120         var settings=this;
121         
122         ['xs','sm','md','lg'].map(function(size){
123             if (settings[size]) {
124                 cfg.cls += ' col-' + size + '-' + settings[size];
125             }
126         });
127         
128         var inputblock = input;
129          
130         if (this.before || this.after) {
131             
132             inputblock = {
133                 cls : 'input-group',
134                 cn :  [] 
135             };
136             
137             if (this.before) {
138                 inputblock.cn.push({
139                     tag :'span',
140                     cls : 'input-group-addon',
141                     html : this.before
142                 });
143             }
144             
145             inputblock.cn.push(input);
146             
147             if(this.inputType != 'radio'){
148                 inputblock.cn.push(hidden);
149             }
150             
151             if (this.after) {
152                 inputblock.cn.push({
153                     tag :'span',
154                     cls : 'input-group-addon',
155                     html : this.after
156                 });
157             }
158             
159         }
160         
161         if (align ==='left' && this.fieldLabel.length) {
162 //                Roo.log("left and has label");
163             cfg.cn = [
164                 {
165                     tag: 'label',
166                     'for' :  id,
167                     cls : 'control-label',
168                     html : this.fieldLabel
169                 },
170                 {
171                     cls : "", 
172                     cn: [
173                         inputblock
174                     ]
175                 }
176             ];
177             
178             if(this.labelWidth > 12){
179                 cfg.cn[0].style = "width: " + this.labelWidth + 'px';
180             }
181             
182             if(this.labelWidth < 13 && this.labelmd == 0){
183                 this.labelmd = this.labelWidth;
184             }
185             
186             if(this.labellg > 0){
187                 cfg.cn[0].cls += ' col-lg-' + this.labellg;
188                 cfg.cn[1].cls += ' col-lg-' + (12 - this.labellg);
189             }
190             
191             if(this.labelmd > 0){
192                 cfg.cn[0].cls += ' col-md-' + this.labelmd;
193                 cfg.cn[1].cls += ' col-md-' + (12 - this.labelmd);
194             }
195             
196             if(this.labelsm > 0){
197                 cfg.cn[0].cls += ' col-sm-' + this.labelsm;
198                 cfg.cn[1].cls += ' col-sm-' + (12 - this.labelsm);
199             }
200             
201             if(this.labelxs > 0){
202                 cfg.cn[0].cls += ' col-xs-' + this.labelxs;
203                 cfg.cn[1].cls += ' col-xs-' + (12 - this.labelxs);
204             }
205             
206         } else if ( this.fieldLabel.length) {
207 //                Roo.log(" label");
208                 cfg.cn = [
209                    
210                     {
211                         tag: this.boxLabel ? 'span' : 'label',
212                         'for': id,
213                         cls: 'control-label box-input-label',
214                         //cls : 'input-group-addon',
215                         html : this.fieldLabel
216                     },
217                     
218                     inputblock
219                     
220                 ];
221
222         } else {
223             
224 //                Roo.log(" no label && no align");
225                 cfg.cn = [  inputblock ] ;
226                 
227                 
228         }
229         
230         if(this.boxLabel){
231              var boxLabelCfg = {
232                 tag: 'label',
233                 //'for': id, // box label is handled by onclick - so no for...
234                 cls: 'box-label',
235                 html: this.boxLabel
236             };
237             
238             if(this.tooltip){
239                 boxLabelCfg.tooltip = this.tooltip;
240             }
241              
242             cfg.cn.push(boxLabelCfg);
243         }
244         
245         if(this.inputType != 'radio'){
246             cfg.cn.push(hidden);
247         }
248         
249         return cfg;
250         
251     },
252     
253     /**
254      * return the real input element.
255      */
256     inputEl: function ()
257     {
258         return this.el.select('input.roo-' + this.inputType,true).first();
259     },
260     hiddenEl: function ()
261     {
262         return this.el.select('input.roo-hidden-value',true).first();
263     },
264     
265     labelEl: function()
266     {
267         return this.el.select('label.control-label',true).first();
268     },
269     /* depricated... */
270     
271     label: function()
272     {
273         return this.labelEl();
274     },
275     
276     boxLabelEl: function()
277     {
278         return this.el.select('label.box-label',true).first();
279     },
280     
281     initEvents : function()
282     {
283 //        Roo.bootstrap.CheckBox.superclass.initEvents.call(this);
284         
285         this.inputEl().on('click', this.onClick,  this);
286         
287         if (this.boxLabel) { 
288             this.el.select('label.box-label',true).first().on('click', this.onClick,  this);
289         }
290         
291         this.startValue = this.getValue();
292         
293         if(this.groupId){
294             Roo.bootstrap.CheckBox.register(this);
295         }
296     },
297     
298     onClick : function(e)
299     {   
300         if(this.fireEvent('click', this, e) !== false){
301             this.setChecked(!this.checked);
302         }
303         
304     },
305     
306     setChecked : function(state,suppressEvent)
307     {
308         this.startValue = this.getValue();
309
310         if(this.inputType == 'radio'){
311             
312             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
313                 e.dom.checked = false;
314             });
315             
316             this.inputEl().dom.checked = true;
317             
318             this.inputEl().dom.value = this.inputValue;
319             
320             if(suppressEvent !== true){
321                 this.fireEvent('check', this, true);
322             }
323             
324             this.validate();
325             
326             return;
327         }
328         
329         this.checked = state;
330         
331         this.inputEl().dom.checked = state;
332         
333         
334         this.hiddenEl().dom.value = state ? this.inputValue : this.valueOff;
335         
336         if(suppressEvent !== true){
337             this.fireEvent('check', this, state);
338         }
339         
340         this.validate();
341     },
342     
343     getValue : function()
344     {
345         if(this.inputType == 'radio'){
346             return this.getGroupValue();
347         }
348         
349         return this.hiddenEl().dom.value;
350         
351     },
352     
353     getGroupValue : function()
354     {
355         if(typeof(this.el.up('form').child('input[name='+this.name+']:checked', true)) == 'undefined'){
356             return '';
357         }
358         
359         return this.el.up('form').child('input[name='+this.name+']:checked', true).value;
360     },
361     
362     setValue : function(v,suppressEvent)
363     {
364         if(this.inputType == 'radio'){
365             this.setGroupValue(v, suppressEvent);
366             return;
367         }
368         
369         this.setChecked(((typeof(v) == 'undefined') ? this.checked : (String(v) === String(this.inputValue))), suppressEvent);
370         
371         this.validate();
372     },
373     
374     setGroupValue : function(v, suppressEvent)
375     {
376         this.startValue = this.getValue();
377         
378         Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
379             e.dom.checked = false;
380             
381             if(e.dom.value == v){
382                 e.dom.checked = true;
383             }
384         });
385         
386         if(suppressEvent !== true){
387             this.fireEvent('check', this, true);
388         }
389
390         this.validate();
391         
392         return;
393     },
394     
395     validate : function()
396     {
397         if(this.getVisibilityEl().hasClass('hidden')){
398             return true;
399         }
400         
401         if(
402                 this.disabled || 
403                 (this.inputType == 'radio' && this.validateRadio()) ||
404                 (this.inputType == 'checkbox' && this.validateCheckbox())
405         ){
406             this.markValid();
407             return true;
408         }
409         
410         this.markInvalid();
411         return false;
412     },
413     
414     validateRadio : function()
415     {
416         if(this.getVisibilityEl().hasClass('hidden')){
417             return true;
418         }
419         
420         if(this.allowBlank){
421             return true;
422         }
423         
424         var valid = false;
425         
426         Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
427             if(!e.dom.checked){
428                 return;
429             }
430             
431             valid = true;
432             
433             return false;
434         });
435         
436         return valid;
437     },
438     
439     validateCheckbox : function()
440     {
441         if(!this.groupId){
442             return (this.getValue() == this.inputValue || this.allowBlank) ? true : false;
443             //return (this.getValue() == this.inputValue) ? true : false;
444         }
445         
446         var group = Roo.bootstrap.CheckBox.get(this.groupId);
447         
448         if(!group){
449             return false;
450         }
451         
452         var r = false;
453         
454         for(var i in group){
455             if(group[i].el.isVisible(true)){
456                 r = false;
457                 break;
458             }
459             
460             r = true;
461         }
462         
463         for(var i in group){
464             if(r){
465                 break;
466             }
467             
468             r = (group[i].getValue() == group[i].inputValue) ? true : false;
469         }
470         
471         return r;
472     },
473     
474     /**
475      * Mark this field as valid
476      */
477     markValid : function()
478     {
479         var _this = this;
480         
481         this.fireEvent('valid', this);
482         
483         var label = Roo.bootstrap.FieldLabel.get(this.name + '-group');
484         
485         if(this.groupId){
486             label = Roo.bootstrap.FieldLabel.get(this.groupId + '-group');
487         }
488         
489         if(label){
490             label.markValid();
491         }
492
493         if(this.inputType == 'radio'){
494             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
495                 e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
496                 e.findParent('.form-group', false, true).addClass(_this.validClass);
497             });
498             
499             return;
500         }
501
502         if(!this.groupId){
503             this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
504             this.el.findParent('.form-group', false, true).addClass(this.validClass);
505             return;
506         }
507         
508         var group = Roo.bootstrap.CheckBox.get(this.groupId);
509         
510         if(!group){
511             return;
512         }
513         
514         for(var i in group){
515             group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
516             group[i].el.findParent('.form-group', false, true).addClass(this.validClass);
517         }
518     },
519     
520      /**
521      * Mark this field as invalid
522      * @param {String} msg The validation message
523      */
524     markInvalid : function(msg)
525     {
526         if(this.allowBlank){
527             return;
528         }
529         
530         var _this = this;
531         
532         this.fireEvent('invalid', this, msg);
533         
534         var label = Roo.bootstrap.FieldLabel.get(this.name + '-group');
535         
536         if(this.groupId){
537             label = Roo.bootstrap.FieldLabel.get(this.groupId + '-group');
538         }
539         
540         if(label){
541             label.markInvalid();
542         }
543             
544         if(this.inputType == 'radio'){
545             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
546                 e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
547                 e.findParent('.form-group', false, true).addClass(_this.invalidClass);
548             });
549             
550             return;
551         }
552         
553         if(!this.groupId){
554             this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
555             this.el.findParent('.form-group', false, true).addClass(this.invalidClass);
556             return;
557         }
558         
559         var group = Roo.bootstrap.CheckBox.get(this.groupId);
560         
561         if(!group){
562             return;
563         }
564         
565         for(var i in group){
566             group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
567             group[i].el.findParent('.form-group', false, true).addClass(this.invalidClass);
568         }
569         
570     },
571     
572     clearInvalid : function()
573     {
574         Roo.bootstrap.Input.prototype.clearInvalid.call(this);
575         
576         // this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
577         
578         var label = Roo.bootstrap.FieldLabel.get(this.name + '-group');
579         
580         if (label && label.iconEl) {
581             label.iconEl.removeClass(label.validClass);
582             label.iconEl.removeClass(label.invalidClass);
583         }
584     },
585     
586     disable : function()
587     {
588         if(this.inputType != 'radio'){
589             Roo.bootstrap.CheckBox.superclass.disable.call(this);
590             return;
591         }
592         
593         var _this = this;
594         
595         if(this.rendered){
596             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
597                 _this.getActionEl().addClass(this.disabledClass);
598                 e.dom.disabled = true;
599             });
600         }
601         
602         this.disabled = true;
603         this.fireEvent("disable", this);
604         return this;
605     },
606
607     enable : function()
608     {
609         if(this.inputType != 'radio'){
610             Roo.bootstrap.CheckBox.superclass.enable.call(this);
611             return;
612         }
613         
614         var _this = this;
615         
616         if(this.rendered){
617             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
618                 _this.getActionEl().removeClass(this.disabledClass);
619                 e.dom.disabled = false;
620             });
621         }
622         
623         this.disabled = false;
624         this.fireEvent("enable", this);
625         return this;
626     },
627     
628     setBoxLabel : function(v)
629     {
630         this.boxLabel = v;
631         
632         if(this.rendered){
633             this.el.select('label.box-label',true).first().dom.innerHTML = (v === null || v === undefined ? '' : v);
634         }
635     }
636
637 });
638
639 Roo.apply(Roo.bootstrap.CheckBox, {
640     
641     groups: {},
642     
643      /**
644     * register a CheckBox Group
645     * @param {Roo.bootstrap.CheckBox} the CheckBox to add
646     */
647     register : function(checkbox)
648     {
649         if(typeof(this.groups[checkbox.groupId]) == 'undefined'){
650             this.groups[checkbox.groupId] = {};
651         }
652         
653         if(this.groups[checkbox.groupId].hasOwnProperty(checkbox.name)){
654             return;
655         }
656         
657         this.groups[checkbox.groupId][checkbox.name] = checkbox;
658         
659     },
660     /**
661     * fetch a CheckBox Group based on the group ID
662     * @param {string} the group ID
663     * @returns {Roo.bootstrap.CheckBox} the CheckBox group
664     */
665     get: function(groupId) {
666         if (typeof(this.groups[groupId]) == 'undefined') {
667             return false;
668         }
669         
670         return this.groups[groupId] ;
671     }
672     
673     
674 });