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