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