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             cfg.cn.push({
111                 tag : 'div',
112                 cls : 'column roo-date-split-field-label col-md-' + ((this.labelAlign == 'top') ? '12' : this.labelWidth),
113                 cn : [
114                     {
115                         tag : 'label',
116                         html : this.fieldLabel
117                     }
118                 ]
119             });
120         }
121         
122         Roo.each(['day', 'month', 'year'], function(t){
123             cfg.cn.push({
124                 tag : 'div',
125                 cls : 'column roo-date-split-field-' + t + ' col-md-' + ((this.labelAlign == 'top') ? '4' : ((12 - this.labelWidth) / 3))
126             });
127         }, this);
128         
129         return cfg;
130     },
131     
132     inputEl: function ()
133     {
134         return this.el.select('.roo-date-split-field-group-value', true).first();
135     },
136     
137     onRender : function(ct, position) 
138     {
139         var _this = this;
140         
141         Roo.bootstrap.NavProgressBar.superclass.onRender.call(this, ct, position);
142         
143         this.inputEl = this.el.select('.roo-date-split-field-group-value', true).first();
144         
145         this.dayField = new Roo.bootstrap.ComboBox({
146             allowBlank : this.dayAllowBlank,
147             alwaysQuery : true,
148             displayField : 'value',
149             editable : false,
150             fieldLabel : '',
151             forceSelection : true,
152             mode : 'local',
153             placeholder : this.dayPlaceholder,
154             selectOnFocus : true,
155             tpl : '<div class="roo-select2-result"><b>{value}</b></div>',
156             triggerAction : 'all',
157             typeAhead : true,
158             valueField : 'value',
159             store : new Roo.data.SimpleStore({
160                 data : (function() {    
161                     var days = [];
162                     _this.fireEvent('days', _this, days);
163                     return days;
164                 })(),
165                 fields : [ 'value' ]
166             }),
167             listeners : {
168                 select : function (_self, record, index)
169                 {
170                     _this.setValue(_this.getValue());
171                 }
172             }
173         });
174
175         this.dayField.render(this.el.select('.roo-date-split-field-day', true).first(), null);
176         
177         this.monthField = new Roo.bootstrap.MonthField({
178             after : '<i class=\"fa fa-calendar\"></i>',
179             allowBlank : this.monthAllowBlank,
180             placeholder : this.monthPlaceholder,
181             readOnly : true,
182             listeners : {
183                 render : function (_self)
184                 {
185                     this.el.select('span.input-group-addon', true).first().on('click', function(e){
186                         e.preventDefault();
187                         _self.focus();
188                     });
189                 },
190                 select : function (_self, oldvalue, newvalue)
191                 {
192                     _this.setValue(_this.getValue());
193                 }
194             }
195         });
196         
197         this.monthField.render(this.el.select('.roo-date-split-field-month', true).first(), null);
198         
199         this.yearField = new Roo.bootstrap.ComboBox({
200             allowBlank : this.yearAllowBlank,
201             alwaysQuery : true,
202             displayField : 'value',
203             editable : false,
204             fieldLabel : '',
205             forceSelection : true,
206             mode : 'local',
207             placeholder : this.yearPlaceholder,
208             selectOnFocus : true,
209             tpl : '<div class="roo-select2-result"><b>{value}</b></div>',
210             triggerAction : 'all',
211             typeAhead : true,
212             valueField : 'value',
213             store : new Roo.data.SimpleStore({
214                 data : (function() {
215                     var years = [];
216                     _this.fireEvent('years', _this, years);
217                     return years;
218                 })(),
219                 fields : [ 'value' ]
220             }),
221             listeners : {
222                 select : function (_self, record, index)
223                 {
224                     _this.setValue(_this.getValue());
225                 }
226             }
227         });
228
229         this.yearField.render(this.el.select('.roo-date-split-field-year', true).first(), null);
230     },
231     
232     setValue : function(v, format)
233     {
234         this.inputEl.dom.value = v;
235         
236         var f = format || (this.yearFormat + '-' + this.monthFormat + '-' + this.dayFormat);
237         
238         var d = Date.parseDate(v, f);
239         
240         if(!d){
241             this.validate();
242             return;
243         }
244         
245         this.setDay(d.format(this.dayFormat));
246         this.setMonth(d.format(this.monthFormat));
247         this.setYear(d.format(this.yearFormat));
248         
249         this.validate();
250         
251         return;
252     },
253     
254     setDay : function(v)
255     {
256         this.dayField.setValue(v);
257         this.inputEl.dom.value = this.getValue();
258         this.validate();
259         return;
260     },
261     
262     setMonth : function(v)
263     {
264         this.monthField.setValue(v, true);
265         this.inputEl.dom.value = this.getValue();
266         this.validate();
267         return;
268     },
269     
270     setYear : function(v)
271     {
272         this.yearField.setValue(v);
273         this.inputEl.dom.value = this.getValue();
274         this.validate();
275         return;
276     },
277     
278     getDay : function()
279     {
280         return this.dayField.getValue();
281     },
282     
283     getMonth : function()
284     {
285         return this.monthField.getValue();
286     },
287     
288     getYear : function()
289     {
290         return this.yearField.getValue();
291     },
292     
293     getValue : function()
294     {
295         var f = this.yearFormat + '-' + this.monthFormat + '-' + this.dayFormat;
296         
297         var date = this.yearField.getValue() + '-' + this.monthField.getValue() + '-' + this.dayField.getValue();
298         
299         return date;
300     },
301     
302     reset : function()
303     {
304         this.setDay('');
305         this.setMonth('');
306         this.setYear('');
307         this.inputEl.dom.value = '';
308         this.validate();
309         return;
310     },
311     
312     validate : function()
313     {
314         var d = this.dayField.validate();
315         var m = this.monthField.validate();
316         var y = this.yearField.validate();
317         
318         var valid = true;
319         
320         if(
321                 (!this.dayAllowBlank && !d) ||
322                 (!this.monthAllowBlank && !m) ||
323                 (!this.yearAllowBlank && !y)
324         ){
325             valid = false;
326         }
327         
328         if(this.dayAllowBlank && this.monthAllowBlank && this.yearAllowBlank){
329             return valid;
330         }
331         
332         if(valid){
333             this.markValid();
334             return valid;
335         }
336         
337         this.markInvalid();
338         
339         return valid;
340     },
341     
342     markValid : function()
343     {
344         
345         var label = this.el.select('label', true).first();
346         var icon = this.el.select('i.fa-star', true).first();
347
348         if(label && icon){
349             icon.remove();
350         }
351         
352         this.fireEvent('valid', this);
353     },
354     
355      /**
356      * Mark this field as invalid
357      * @param {String} msg The validation message
358      */
359     markInvalid : function(msg)
360     {
361         
362         var label = this.el.select('label', true).first();
363         var icon = this.el.select('i.fa-star', true).first();
364
365         if(label && !icon){
366             this.el.select('.roo-date-split-field-label', true).createChild({
367                 tag : 'i',
368                 cls : 'text-danger fa fa-lg fa-star',
369                 tooltip : 'This field is required',
370                 style : 'margin-right:5px;'
371             }, label, true);
372         }
373         
374         this.fireEvent('invalid', this, msg);
375     },
376     
377     clearInvalid : function()
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     getName: function()
390     {
391         return this.name;
392     }
393     
394 });
395
396