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