Roo/bootstrap/DateSplitField.js
[roojs1] / Roo / bootstrap / DateSplitField.js
1 /*
2  * - LGPL
3  *
4  * page DateSplitField.
5  * 
6  */
7
8
9 /**
10  * @class Roo.bootstrap.DateSplitField
11  * @extends Roo.bootstrap.Component
12  * Bootstrap DateSplitField class
13  * @cfg {string} fieldLabel - the label associated
14  * @cfg {Number} labelWidth set the width of label (0-12)
15  * @cfg {String} labelAlign (top|left)
16  * @cfg {Boolean} dayAllowBlank (true|false) default false
17  * @cfg {Boolean} monthAllowBlank (true|false) default false
18  * @cfg {Boolean} yearAllowBlank (true|false) default false
19  * @cfg {string} dayPlaceholder 
20  * @cfg {string} monthPlaceholder
21  * @cfg {string} yearPlaceholder
22  * @cfg {string} dayFormat default 'd'
23  * @cfg {string} monthFormat default 'm'
24  * @cfg {string} yearFormat default 'Y'
25  * @cfg {Number} labellg set the width of label (1-12)
26  * @cfg {Number} labelmd set the width of label (1-12)
27  * @cfg {Number} labelsm set the width of label (1-12)
28  * @cfg {Number} labelxs set the width of label (1-12)
29
30  *     
31  * @constructor
32  * Create a new DateSplitField
33  * @param {Object} config The config object
34  */
35
36 Roo.bootstrap.DateSplitField = function(config){
37     Roo.bootstrap.DateSplitField.superclass.constructor.call(this, config);
38     
39     this.addEvents({
40         // raw events
41          /**
42          * @event years
43          * getting the data of years
44          * @param {Roo.bootstrap.DateSplitField} this
45          * @param {Object} years
46          */
47         "years" : true,
48         /**
49          * @event days
50          * getting the data of days
51          * @param {Roo.bootstrap.DateSplitField} this
52          * @param {Object} days
53          */
54         "days" : true,
55         /**
56          * @event invalid
57          * Fires after the field has been marked as invalid.
58          * @param {Roo.form.Field} this
59          * @param {String} msg The validation message
60          */
61         invalid : true,
62        /**
63          * @event valid
64          * Fires after the field has been validated with no errors.
65          * @param {Roo.form.Field} this
66          */
67         valid : true
68     });
69 };
70
71 Roo.extend(Roo.bootstrap.DateSplitField, Roo.bootstrap.Component,  {
72     
73     fieldLabel : '',
74     labelAlign : 'top',
75     labelWidth : 3,
76     dayAllowBlank : false,
77     monthAllowBlank : false,
78     yearAllowBlank : false,
79     dayPlaceholder : '',
80     monthPlaceholder : '',
81     yearPlaceholder : '',
82     dayFormat : 'd',
83     monthFormat : 'm',
84     yearFormat : 'Y',
85     isFormField : true,
86     labellg : 0,
87     labelmd : 0,
88     labelsm : 0,
89     labelxs : 0,
90     
91     getAutoCreate : function()
92     {
93         var cfg = {
94             tag : 'div',
95             cls : 'row roo-date-split-field-group',
96             cn : [
97                 {
98                     tag : 'input',
99                     type : 'hidden',
100                     cls : 'form-hidden-field roo-date-split-field-group-value',
101                     name : this.name
102                 }
103             ]
104         };
105         
106         var labelCls = 'col-md-12';
107         var contentCls = 'col-md-4';
108         
109         if(this.fieldLabel){
110             
111             var label = {
112                 tag : 'div',
113                 cls : 'column roo-date-split-field-label col-md-' + ((this.labelAlign == 'top') ? '12' : this.labelWidth),
114                 cn : [
115                     {
116                         tag : 'label',
117                         html : this.fieldLabel
118                     }
119                 ]
120             };
121             
122             if(this.labelAlign == 'left'){
123             
124                 if(this.labelWidth > 12){
125                     labelCfg.style = "width: " + this.labelWidth + 'px';
126                 }
127
128                 if(this.labelWidth < 13 && this.labelmd == 0){
129                     this.labelmd = this.labelWidth;
130                 }
131
132                 if(this.labellg > 0){
133                     labelCfg.cls += ' col-lg-' + this.labellg;
134                     contentCfg.cls += ' col-lg-' + (12 - this.labellg);
135                 }
136
137                 if(this.labelmd > 0){
138                     labelCfg.cls += ' col-md-' + this.labelmd;
139                     contentCfg.cls += ' col-md-' + (12 - this.labelmd);
140                 }
141
142                 if(this.labelsm > 0){
143                     labelCfg.cls += ' col-sm-' + this.labelsm;
144                     contentCfg.cls += ' col-sm-' + (12 - this.labelsm);
145                 }
146
147                 if(this.labelxs > 0){
148                     labelCfg.cls += ' col-xs-' + this.labelxs;
149                     contentCfg.cls += ' col-xs-' + (12 - this.labelxs);
150                 }
151             }
152             
153             cfg.cn.push(label);
154         }
155         
156         Roo.each(['day', 'month', 'year'], function(t){
157             cfg.cn.push({
158                 tag : 'div',
159                 cls : 'column roo-date-split-field-' + t + ' col-md-' + ((this.labelAlign == 'top') ? '4' : ((12 - this.labelWidth) / 3))
160             });
161         }, this);
162         
163         return cfg;
164     },
165     
166     inputEl: function ()
167     {
168         return this.el.select('.roo-date-split-field-group-value', true).first();
169     },
170     
171     onRender : function(ct, position) 
172     {
173         var _this = this;
174         
175         Roo.bootstrap.NavProgressBar.superclass.onRender.call(this, ct, position);
176         
177         this.inputEl = this.el.select('.roo-date-split-field-group-value', true).first();
178         
179         this.dayField = new Roo.bootstrap.ComboBox({
180             allowBlank : this.dayAllowBlank,
181             alwaysQuery : true,
182             displayField : 'value',
183             editable : false,
184             fieldLabel : '',
185             forceSelection : true,
186             mode : 'local',
187             placeholder : this.dayPlaceholder,
188             selectOnFocus : true,
189             tpl : '<div class="roo-select2-result"><b>{value}</b></div>',
190             triggerAction : 'all',
191             typeAhead : true,
192             valueField : 'value',
193             store : new Roo.data.SimpleStore({
194                 data : (function() {    
195                     var days = [];
196                     _this.fireEvent('days', _this, days);
197                     return days;
198                 })(),
199                 fields : [ 'value' ]
200             }),
201             listeners : {
202                 select : function (_self, record, index)
203                 {
204                     _this.setValue(_this.getValue());
205                 }
206             }
207         });
208
209         this.dayField.render(this.el.select('.roo-date-split-field-day', true).first(), null);
210         
211         this.monthField = new Roo.bootstrap.MonthField({
212             after : '<i class=\"fa fa-calendar\"></i>',
213             allowBlank : this.monthAllowBlank,
214             placeholder : this.monthPlaceholder,
215             readOnly : true,
216             listeners : {
217                 render : function (_self)
218                 {
219                     this.el.select('span.input-group-addon', true).first().on('click', function(e){
220                         e.preventDefault();
221                         _self.focus();
222                     });
223                 },
224                 select : function (_self, oldvalue, newvalue)
225                 {
226                     _this.setValue(_this.getValue());
227                 }
228             }
229         });
230         
231         this.monthField.render(this.el.select('.roo-date-split-field-month', true).first(), null);
232         
233         this.yearField = new Roo.bootstrap.ComboBox({
234             allowBlank : this.yearAllowBlank,
235             alwaysQuery : true,
236             displayField : 'value',
237             editable : false,
238             fieldLabel : '',
239             forceSelection : true,
240             mode : 'local',
241             placeholder : this.yearPlaceholder,
242             selectOnFocus : true,
243             tpl : '<div class="roo-select2-result"><b>{value}</b></div>',
244             triggerAction : 'all',
245             typeAhead : true,
246             valueField : 'value',
247             store : new Roo.data.SimpleStore({
248                 data : (function() {
249                     var years = [];
250                     _this.fireEvent('years', _this, years);
251                     return years;
252                 })(),
253                 fields : [ 'value' ]
254             }),
255             listeners : {
256                 select : function (_self, record, index)
257                 {
258                     _this.setValue(_this.getValue());
259                 }
260             }
261         });
262
263         this.yearField.render(this.el.select('.roo-date-split-field-year', true).first(), null);
264     },
265     
266     setValue : function(v, format)
267     {
268         this.inputEl.dom.value = v;
269         
270         var f = format || (this.yearFormat + '-' + this.monthFormat + '-' + this.dayFormat);
271         
272         var d = Date.parseDate(v, f);
273         
274         if(!d){
275             this.validate();
276             return;
277         }
278         
279         this.setDay(d.format(this.dayFormat));
280         this.setMonth(d.format(this.monthFormat));
281         this.setYear(d.format(this.yearFormat));
282         
283         this.validate();
284         
285         return;
286     },
287     
288     setDay : function(v)
289     {
290         this.dayField.setValue(v);
291         this.inputEl.dom.value = this.getValue();
292         this.validate();
293         return;
294     },
295     
296     setMonth : function(v)
297     {
298         this.monthField.setValue(v, true);
299         this.inputEl.dom.value = this.getValue();
300         this.validate();
301         return;
302     },
303     
304     setYear : function(v)
305     {
306         this.yearField.setValue(v);
307         this.inputEl.dom.value = this.getValue();
308         this.validate();
309         return;
310     },
311     
312     getDay : function()
313     {
314         return this.dayField.getValue();
315     },
316     
317     getMonth : function()
318     {
319         return this.monthField.getValue();
320     },
321     
322     getYear : function()
323     {
324         return this.yearField.getValue();
325     },
326     
327     getValue : function()
328     {
329         var f = this.yearFormat + '-' + this.monthFormat + '-' + this.dayFormat;
330         
331         var date = this.yearField.getValue() + '-' + this.monthField.getValue() + '-' + this.dayField.getValue();
332         
333         return date;
334     },
335     
336     reset : function()
337     {
338         this.setDay('');
339         this.setMonth('');
340         this.setYear('');
341         this.inputEl.dom.value = '';
342         this.validate();
343         return;
344     },
345     
346     validate : function()
347     {
348         var d = this.dayField.validate();
349         var m = this.monthField.validate();
350         var y = this.yearField.validate();
351         
352         var valid = true;
353         
354         if(
355                 (!this.dayAllowBlank && !d) ||
356                 (!this.monthAllowBlank && !m) ||
357                 (!this.yearAllowBlank && !y)
358         ){
359             valid = false;
360         }
361         
362         if(this.dayAllowBlank && this.monthAllowBlank && this.yearAllowBlank){
363             return valid;
364         }
365         
366         if(valid){
367             this.markValid();
368             return valid;
369         }
370         
371         this.markInvalid();
372         
373         return valid;
374     },
375     
376     markValid : function()
377     {
378         
379         var label = this.el.select('label', true).first();
380         var icon = this.el.select('i.fa-star', true).first();
381
382         if(label && icon){
383             icon.remove();
384         }
385         
386         this.fireEvent('valid', this);
387     },
388     
389      /**
390      * Mark this field as invalid
391      * @param {String} msg The validation message
392      */
393     markInvalid : function(msg)
394     {
395         
396         var label = this.el.select('label', true).first();
397         var icon = this.el.select('i.fa-star', true).first();
398
399         if(label && !icon){
400             this.el.select('.roo-date-split-field-label', true).createChild({
401                 tag : 'i',
402                 cls : 'text-danger fa fa-lg fa-star',
403                 tooltip : 'This field is required',
404                 style : 'margin-right:5px;'
405             }, label, true);
406         }
407         
408         this.fireEvent('invalid', this, msg);
409     },
410     
411     clearInvalid : function()
412     {
413         var label = this.el.select('label', true).first();
414         var icon = this.el.select('i.fa-star', true).first();
415
416         if(label && icon){
417             icon.remove();
418         }
419         
420         this.fireEvent('valid', this);
421     },
422     
423     getName: function()
424     {
425         return this.name;
426     }
427     
428 });
429
430