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  * 
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     invalidClass : "has-warning",
44     validClass : "has-success",
45     inputType: 'checkbox',
46     inputValue: 1,
47     valueOff: 0,
48     boxLabel: false,
49     checked: false,
50     weight : false,
51     inline: 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.getValue().length) ||
332                 (this.inputType == 'checkbox' && this.validateGroup())
333         ){
334             this.markValid();
335             return true;
336         }
337         
338         this.markInvalid();
339         return false;
340     },
341     
342     validateGroup : function()
343     {
344         if(!this.groupId){
345             return (this.getValue() == this.inputValue) ? true : false;
346         }
347         
348         var group = Roo.bootstrap.CheckBox.get(this.groupId);
349         
350         if(!group){
351             return false;
352         }
353         
354         var r = false;
355         
356         for(var i in group){
357             if(r){
358                 break;
359             }
360             
361             r = (group[i].getValue() == group[i].inputValue) ? true : false;
362         }
363         
364         return r;
365     },
366     
367     /**
368      * Mark this field as valid
369      */
370     markValid : function()
371     {
372         var _this = this;
373         
374         this.fireEvent('valid', this);
375         
376         if(this.inputType == 'radio'){
377             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
378                 e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
379                 e.findParent('.form-group', false, true).addClass(_this.validClass);
380             });
381             
382             return;
383         }
384         
385         if(!this.groupId){
386             this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
387             this.el.findParent('.form-group', false, true).addClass(this.validClass);
388             return;
389         }
390         
391         var group = Roo.bootstrap.CheckBox.get(this.groupId);
392             
393         if(!group){
394             return;
395         }
396         
397         for(var i in group){
398             group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
399             group[i].el.findParent('.form-group', false, true).addClass(this.validClass);
400         }
401     },
402     
403      /**
404      * Mark this field as invalid
405      * @param {String} msg The validation message
406      */
407     markInvalid : function(msg)
408     {
409         var _this = this;
410         
411         this.fireEvent('invalid', this, msg);
412         
413         if(this.inputType == 'radio'){
414             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
415                 e.findParent('.form-group', false, true).removeClass([_this.invalidClass, _this.validClass]);
416                 e.findParent('.form-group', false, true).addClass(_this.invalidClass);
417             });
418             
419             return;
420         }
421         
422         if(!this.groupId){
423             this.el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
424             this.el.findParent('.form-group', false, true).addClass(this.invalidClass);
425             return;
426         }
427         
428         var group = Roo.bootstrap.CheckBox.get(this.groupId);
429             
430         if(!group){
431             return;
432         }
433         
434         for(var i in group){
435             group[i].el.findParent('.form-group', false, true).removeClass([this.invalidClass, this.validClass]);
436             group[i].el.findParent('.form-group', false, true).addClass(this.invalidClass);
437         }
438         
439     }
440     
441 });
442
443 Roo.apply(Roo.bootstrap.CheckBox, {
444     
445     groups: {},
446     
447      /**
448     * register a CheckBox Group
449     * @param {Roo.bootstrap.CheckBox} the CheckBox to add
450     */
451     register : function(checkbox)
452     {
453         if(typeof(this.groups[checkbox.groupId]) == 'undefined'){
454             this.groups[checkbox.groupId] = {};
455         }
456         
457         if(this.groups[checkbox.groupId].hasOwnProperty(checkbox.name)){
458             return;
459         }
460         
461         this.groups[checkbox.groupId][checkbox.name] = checkbox;
462         
463     },
464     /**
465     * fetch a CheckBox Group based on the group ID
466     * @param {string} the group ID
467     * @returns {Roo.bootstrap.CheckBox} the CheckBox group
468     */
469     get: function(groupId) {
470         if (typeof(this.groups[groupId]) == 'undefined') {
471             return false;
472         }
473         
474         return this.groups[groupId] ;
475     }
476     
477     
478 });