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             return;
258         }
259         
260         this.checked = state;
261         
262         this.inputEl().dom.checked = state;
263         
264         this.inputEl().dom.value = state ? this.inputValue : this.valueOff;
265         
266         if(suppressEvent !== true){
267             this.fireEvent('check', this, state);
268         }
269     },
270     
271     getValue : function()
272     {
273         if(this.inputType == 'radio'){
274             return this.getGroupValue();
275         }
276         
277         return this.inputEl().getValue();
278         
279     },
280     
281     getGroupValue : function()
282     {
283         if(typeof(this.el.up('form').child('input[name='+this.name+']:checked', true)) == 'undefined'){
284             return '';
285         }
286         
287         return this.el.up('form').child('input[name='+this.name+']:checked', true).value;
288     },
289     
290     setValue : function(v,suppressEvent)
291     {
292         if(this.inputType == 'radio'){
293             this.setGroupValue(v, suppressEvent);
294             this.validate();
295             return;
296         }
297         
298         this.setChecked(((typeof(v) == 'undefined') ? this.checked : (String(v) === String(this.inputValue))), suppressEvent);
299         this.validate();
300     },
301     
302     setGroupValue : function(v, suppressEvent)
303     {
304         this.startValue = this.getValue();
305         
306         Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
307             e.dom.checked = false;
308             
309             if(e.dom.value == v){
310                 e.dom.checked = true;
311             }
312         });
313         
314         if(suppressEvent !== true){
315             this.fireEvent('check', this, true);
316         }
317
318         return;
319     },
320     
321     validate : function()
322     {
323         if(
324                 this.disabled || 
325                 (this.inputType == 'radio' && this.getValue().length) ||
326                 (this.inputType == 'checkbox' && this.validateGroup())
327         ){
328             this.markValid();
329             return true;
330         }
331         
332         this.markInvalid();
333         return false;
334     },
335     
336     validateGroup : function()
337     {
338         if(!this.groupId){
339             return (this.getValue() == this.inputValue) ? true : false;
340         }
341         
342         var group = Roo.bootstrap.CheckBox.get(this.groupId);
343         
344         if(!group){
345             return false;
346         }
347         
348         var r = false;
349         
350         for(var i in group){
351             if(r){
352                 break;
353             }
354             
355             r = (group[i].getValue() == group[i].inputValue) ? true : false;
356         }
357         
358         return r;
359     },
360     
361     /**
362      * Mark this field as valid
363      */
364     markValid : function()
365     {
366         this.fireEvent('valid', this);
367         
368         if(this.inputType == 'radio'){
369             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
370                 e.removeClass([this.invalidClass, this.validClass]);
371                 e.addClass(this.validClass);
372             });
373             
374             return;
375         }
376         
377         if(!this.groupId){
378             this.el.removeClass([this.invalidClass, this.validClass]);
379             this.el.addClass(this.validClass);
380             return;
381         }
382         
383         var group = Roo.bootstrap.CheckBox.get(this.groupId);
384             
385         if(!group){
386             return;
387         }
388         
389         for(var i in group){
390             group[i].el.removeClass([this.invalidClass, this.validClass]);
391             group[i].el.addClass(this.validClass);
392         }
393     },
394     
395      /**
396      * Mark this field as invalid
397      * @param {String} msg The validation message
398      */
399     markInvalid : function(msg)
400     {
401         this.fireEvent('invalid', this, msg);
402         
403         if(this.inputType == 'radio'){
404             Roo.each(this.el.up('form').select('input[name='+this.name+']', true).elements, function(e){
405                 e.removeClass([this.invalidClass, this.validClass]);
406                 e.addClass(this.invalidClass);
407             });
408             
409             return;
410         }
411         
412         if(!this.groupId){
413             this.el.removeClass([this.invalidClass, this.validClass]);
414             this.el.addClass(this.invalidClass);
415             return;
416         }
417         
418         var group = Roo.bootstrap.CheckBox.get(this.groupId);
419             
420         if(!group){
421             return;
422         }
423         
424         for(var i in group){
425             group[i].el.removeClass([this.invalidClass, this.validClass]);
426             group[i].el.addClass(this.invalidClass);
427         }
428         
429     }
430     
431 });
432
433 Roo.apply(Roo.bootstrap.CheckBox, {
434     
435     groups: {},
436     
437      /**
438     * register a CheckBox Group
439     * @param {Roo.bootstrap.CheckBox} the CheckBox to add
440     */
441     register : function(checkbox)
442     {
443         if(typeof(this.groups[checkbox.groupId]) == 'undefined'){
444             this.groups[checkbox.groupId] = {};
445         }
446         
447         if(this.groups[checkbox.groupId].hasOwnProperty(checkbox.name)){
448             return;
449         }
450         
451         this.groups[checkbox.groupId][checkbox.name] = checkbox;
452         
453     },
454     /**
455     * fetch a CheckBox Group based on the group ID
456     * @param {string} the group ID
457     * @returns {Roo.bootstrap.CheckBox} the CheckBox group
458     */
459     get: function(groupId) {
460         if (typeof(this.groups[groupId]) == 'undefined') {
461             return false;
462         }
463         
464         return this.groups[groupId] ;
465     }
466     
467     
468 });