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