3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.form.field.Date
17 * @extends Ext.form.field.Picker
19 Provides a date input field with a {@link Ext.picker.Date date picker} dropdown and automatic date
22 This field recognizes and uses the JavaScript Date object as its main {@link #value} type. In addition,
23 it recognizes string values which are parsed according to the {@link #format} and/or {@link #altFormats}
24 configs. These may be reconfigured to use date formats appropriate for the user's locale.
26 The field may be limited to a certain range of dates by using the {@link #minValue}, {@link #maxValue},
27 {@link #disabledDays}, and {@link #disabledDates} config parameters. These configurations will be used both
28 in the field's validation, and in the date picker dropdown by preventing invalid dates from being selected.
29 {@img Ext.form.Date/Ext.form.Date.png Ext.form.Date component}
32 Ext.create('Ext.form.Panel', {
41 maxValue: new Date() // limited to the current date or prior
47 value: new Date() // defaults to today
49 renderTo: Ext.getBody()
52 #Date Formats Examples#
54 This example shows a couple of different date format parsing scenarios. Both use custom date format
55 configurations; the first one matches the configured `format` while the second matches the `altFormats`.
57 Ext.create('Ext.form.Panel', {
58 renderTo: Ext.getBody(),
67 // The value matches the format; will be parsed and displayed using that format.
75 // The value does not match the format, but does match an altFormat; will be parsed
76 // using the altFormat and displayed using the format.
78 altFormats: 'm,d,Y|m.d.Y',
85 * @docauthor Jason Johnston <jason@sencha.com>
87 Ext.define('Ext.form.field.Date', {
88 extend:'Ext.form.field.Picker',
89 alias: 'widget.datefield',
90 requires: ['Ext.picker.Date'],
91 alternateClassName: ['Ext.form.DateField', 'Ext.form.Date'],
94 * @cfg {String} format
95 * The default date format string which can be overriden for localization support. The format must be
96 * valid according to {@link Ext.Date#parse} (defaults to <tt>'m/d/Y'</tt>).
100 * @cfg {String} altFormats
101 * Multiple date formats separated by "<tt>|</tt>" to try when parsing a user input value and it
102 * does not match the defined format (defaults to
103 * <tt>'m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j'</tt>).
105 altFormats : "m/d/Y|n/j/Y|n/j/y|m/j/y|n/d/y|m/j/Y|n/d/Y|m-d-y|m-d-Y|m/d|m-d|md|mdy|mdY|d|Y-m-d|n-j|n/j",
107 * @cfg {String} disabledDaysText
108 * The tooltip to display when the date falls on a disabled day (defaults to <tt>'Disabled'</tt>)
110 disabledDaysText : "Disabled",
112 * @cfg {String} disabledDatesText
113 * The tooltip text to display when the date falls on a disabled date (defaults to <tt>'Disabled'</tt>)
115 disabledDatesText : "Disabled",
117 * @cfg {String} minText
118 * The error text to display when the date in the cell is before <tt>{@link #minValue}</tt> (defaults to
119 * <tt>'The date in this field must be after {minValue}'</tt>).
121 minText : "The date in this field must be equal to or after {0}",
123 * @cfg {String} maxText
124 * The error text to display when the date in the cell is after <tt>{@link #maxValue}</tt> (defaults to
125 * <tt>'The date in this field must be before {maxValue}'</tt>).
127 maxText : "The date in this field must be equal to or before {0}",
129 * @cfg {String} invalidText
130 * The error text to display when the date in the field is invalid (defaults to
131 * <tt>'{value} is not a valid date - it must be in the format {format}'</tt>).
133 invalidText : "{0} is not a valid date - it must be in the format {1}",
135 * @cfg {String} triggerCls
136 * An additional CSS class used to style the trigger button. The trigger will always get the
137 * class <tt>'x-form-trigger'</tt> and <tt>triggerCls</tt> will be <b>appended</b> if specified
138 * (defaults to <tt>'x-form-date-trigger'</tt> which displays a calendar icon).
140 triggerCls : Ext.baseCSSPrefix + 'form-date-trigger',
142 * @cfg {Boolean} showToday
143 * <tt>false</tt> to hide the footer area of the Date picker containing the Today button and disable
144 * the keyboard handler for spacebar that selects the current date (defaults to <tt>true</tt>).
148 * @cfg {Date/String} minValue
149 * The minimum allowed date. Can be either a Javascript date object or a string date in a
150 * valid format (defaults to undefined).
153 * @cfg {Date/String} maxValue
154 * The maximum allowed date. Can be either a Javascript date object or a string date in a
155 * valid format (defaults to undefined).
158 * @cfg {Array} disabledDays
159 * An array of days to disable, 0 based (defaults to undefined). Some examples:<pre><code>
160 // disable Sunday and Saturday:
163 disabledDays: [1,2,3,4,5]
167 * @cfg {Array} disabledDates
168 * An array of "dates" to disable, as strings. These strings will be used to build a dynamic regular
169 * expression so they are very powerful. Some examples:<pre><code>
170 // disable these exact dates:
171 disabledDates: ["03/08/2003", "09/16/2003"]
172 // disable these days for every year:
173 disabledDates: ["03/08", "09/16"]
174 // only match the beginning (useful if you are using short years):
175 disabledDates: ["^03/08"]
176 // disable every day in March 2006:
177 disabledDates: ["03/../2006"]
178 // disable every day in every March:
179 disabledDates: ["^03"]
181 * Note that the format of the dates included in the array should exactly match the {@link #format} config.
182 * In order to support regular expressions, if you are using a {@link #format date format} that has "." in
183 * it, you will have to escape the dot when restricting dates. For example: <tt>["03\\.08\\.03"]</tt>.
187 * @cfg {String} submitFormat The date format string which will be submitted to the server.
188 * The format must be valid according to {@link Ext.Date#parse} (defaults to <tt>{@link #format}</tt>).
191 // in the absence of a time value, a default value of 12 noon will be used
192 // (note: 12 noon was chosen because it steers well clear of all DST timezone changes)
193 initTime: '12', // 24 hour format
197 matchFieldWidth: false,
199 * @cfg {Number} startDay
200 * Day index at which the week should begin, 0-based (defaults to 0, which is Sunday)
204 initComponent : function(){
206 isString = Ext.isString,
212 me.minValue = me.parseDate(min);
215 me.maxValue = me.parseDate(max);
217 me.disabledDatesRE = null;
218 me.initDisabledDays();
223 initValue: function() {
227 // If a String value was supplied, try to convert it to a proper Date
228 if (Ext.isString(value)) {
229 me.value = me.rawToValue(value);
236 initDisabledDays : function(){
237 if(this.disabledDates){
238 var dd = this.disabledDates,
242 Ext.each(dd, function(d, i){
243 re += Ext.isDate(d) ? '^' + Ext.String.escapeRegex(d.dateFormat(this.format)) + '$' : dd[i];
248 this.disabledDatesRE = new RegExp(re + ')');
253 * Replaces any existing disabled dates with new values and refreshes the Date picker.
254 * @param {Array} disabledDates An array of date strings (see the <tt>{@link #disabledDates}</tt> config
255 * for details on supported values) used to disable a pattern of dates.
257 setDisabledDates : function(dd){
261 me.disabledDates = dd;
262 me.initDisabledDays();
264 picker.setDisabledDates(me.disabledDatesRE);
269 * Replaces any existing disabled days (by index, 0-6) with new values and refreshes the Date picker.
270 * @param {Array} disabledDays An array of disabled day indexes. See the <tt>{@link #disabledDays}</tt>
271 * config for details on supported values.
273 setDisabledDays : function(dd){
274 var picker = this.picker;
276 this.disabledDays = dd;
278 picker.setDisabledDays(dd);
283 * Replaces any existing <tt>{@link #minValue}</tt> with the new value and refreshes the Date picker.
284 * @param {Date} value The minimum date that can be selected
286 setMinValue : function(dt){
289 minValue = (Ext.isString(dt) ? me.parseDate(dt) : dt);
291 me.minValue = minValue;
293 picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue));
294 picker.setMinDate(minValue);
299 * Replaces any existing <tt>{@link #maxValue}</tt> with the new value and refreshes the Date picker.
300 * @param {Date} value The maximum date that can be selected
302 setMaxValue : function(dt){
305 maxValue = (Ext.isString(dt) ? me.parseDate(dt) : dt);
307 me.maxValue = maxValue;
309 picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue));
310 picker.setMaxDate(maxValue);
315 * Runs all of Date's validations and returns an array of any errors. Note that this first
316 * runs Text's validations, so the returned array is an amalgamation of all field errors.
317 * The additional validation checks are testing that the date format is valid, that the chosen
318 * date is within the min and max date constraints set, that the date chosen is not in the disabledDates
319 * regex and that the day chosed is not one of the disabledDays.
320 * @param {Mixed} value The value to get errors for (defaults to the current field value)
321 * @return {Array} All validation errors for this field
323 getErrors: function(value) {
325 format = Ext.String.format,
326 clearTime = Ext.Date.clearTime,
327 errors = me.callParent(arguments),
328 disabledDays = me.disabledDays,
329 disabledDatesRE = me.disabledDatesRE,
330 minValue = me.minValue,
331 maxValue = me.maxValue,
332 len = disabledDays ? disabledDays.length : 0,
339 value = me.formatDate(value || me.processRawValue(me.getRawValue()));
341 if (value === null || value.length < 1) { // if it's blank and textfield didn't flag it then it's valid
346 value = me.parseDate(value);
348 errors.push(format(me.invalidText, svalue, me.format));
352 time = value.getTime();
353 if (minValue && time < clearTime(minValue).getTime()) {
354 errors.push(format(me.minText, me.formatDate(minValue)));
357 if (maxValue && time > clearTime(maxValue).getTime()) {
358 errors.push(format(me.maxText, me.formatDate(maxValue)));
362 day = value.getDay();
364 for(; i < len; i++) {
365 if (day === disabledDays[i]) {
366 errors.push(me.disabledDaysText);
372 fvalue = me.formatDate(value);
373 if (disabledDatesRE && disabledDatesRE.test(fvalue)) {
374 errors.push(format(me.disabledDatesText, fvalue));
380 rawToValue: function(rawValue) {
381 return this.parseDate(rawValue) || rawValue || null;
384 valueToRaw: function(value) {
385 return this.formatDate(this.parseDate(value));
389 * Sets the value of the date field. You can pass a date object or any string that can be
390 * parsed into a valid date, using <tt>{@link #format}</tt> as the date format, according
391 * to the same rules as {@link Ext.Date#parse} (the default format used is <tt>"m/d/Y"</tt>).
394 //All of these calls set the same date value (May 4, 2006)
396 //Pass a date object:
397 var dt = new Date('5/4/2006');
398 dateField.setValue(dt);
400 //Pass a date string (default format):
401 dateField.setValue('05/04/2006');
403 //Pass a date string (custom format):
404 dateField.format = 'Y-m-d';
405 dateField.setValue('2006-05-04');
407 * @param {String/Date} date The date or valid date string
408 * @return {Ext.form.field.Date} this
413 * Attempts to parse a given string value using a given {@link Ext.Date#parse date format}.
414 * @param {String} value The value to attempt to parse
415 * @param {String} format A valid date format (see {@link Ext.Date#parse})
416 * @return {Date} The parsed Date object, or null if the value could not be successfully parsed.
418 safeParse : function(value, format) {
424 if (utilDate.formatContainsHourInfo(format)) {
425 // if parse format contains hour information, no DST adjustment is necessary
426 result = utilDate.parse(value, format);
428 // set time to 12 noon, then clear the time
429 parsedDate = utilDate.parse(value + ' ' + me.initTime, format + ' ' + me.initTimeFormat);
431 result = utilDate.clearTime(parsedDate);
438 getSubmitValue: function() {
440 format = me.submitFormat || me.format,
441 value = me.getValue();
443 return value ? Ext.Date.format(value, format) : null;
449 parseDate : function(value) {
450 if(!value || Ext.isDate(value)){
455 val = me.safeParse(value, me.format),
456 altFormats = me.altFormats,
457 altFormatsArray = me.altFormatsArray,
461 if (!val && altFormats) {
462 altFormatsArray = altFormatsArray || altFormats.split('|');
463 len = altFormatsArray.length;
464 for (; i < len && !val; ++i) {
465 val = me.safeParse(value, altFormatsArray[i]);
472 formatDate : function(date){
473 return Ext.isDate(date) ? Ext.Date.dateFormat(date, this.format) : date;
476 createPicker: function() {
478 format = Ext.String.format;
480 return Ext.create('Ext.picker.Date', {
482 renderTo: document.body,
486 minDate: me.minValue,
487 maxDate: me.maxValue,
488 disabledDatesRE: me.disabledDatesRE,
489 disabledDatesText: me.disabledDatesText,
490 disabledDays: me.disabledDays,
491 disabledDaysText: me.disabledDaysText,
493 showToday: me.showToday,
494 startDay: me.startDay,
495 minText: format(me.minText, me.formatDate(me.minValue)),
496 maxText: format(me.maxText, me.formatDate(me.maxValue)),
509 onSelect: function(m, d) {
513 me.fireEvent('select', me, d);
519 * Sets the Date picker's value to match the current field value when expanding.
521 onExpand: function() {
523 value = me.getValue();
524 me.picker.setValue(Ext.isDate(value) ? value : new Date());
529 * Focuses the field when collapsing the Date picker.
531 onCollapse: function() {
532 this.focus(false, 60);
536 beforeBlur : function(){
538 v = me.parseDate(me.getRawValue()),
539 focusTask = me.focusTask;
551 * @cfg {Boolean} grow @hide
554 * @cfg {Number} growMin @hide
557 * @cfg {Number} growMax @hide