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