formvalidation
Version:
The best jQuery plugin to validate form fields. Support Bootstrap, Foundation, Pure, SemanticUI, UIKit and custom frameworks
368 lines (333 loc) • 14.5 kB
JavaScript
/**
* date validator
*
* @link http://formvalidation.io/validators/date/
* @author https://twitter.com/nghuuphuoc
* @copyright (c) 2013 - 2015 Nguyen Huu Phuoc
* @license http://formvalidation.io/license/
*/
(function($) {
FormValidation.I18n = $.extend(true, FormValidation.I18n || {}, {
'en_US': {
date: {
'default': 'Please enter a valid date',
min: 'Please enter a date after %s',
max: 'Please enter a date before %s',
range: 'Please enter a date in the range %s - %s'
}
}
});
FormValidation.Validator.date = {
html5Attributes: {
message: 'message',
format: 'format',
min: 'min',
max: 'max',
separator: 'separator'
},
/**
* Return true if the input value is valid date
*
* @param {FormValidation.Base} validator The validator plugin instance
* @param {jQuery} $field Field element
* @param {Object} options Can consist of the following keys:
* - message: The invalid message
* - min: the minimum date
* - max: the maximum date
* - separator: Use to separate the date, month, and year.
* By default, it is /
* - format: The date format. Default is MM/DD/YYYY
* The format can be:
*
* i) date: Consist of DD, MM, YYYY parts which are separated by the separator option
* ii) date and time:
* The time can consist of h, m, s parts which are separated by :
* ii) date, time and A (indicating AM or PM)
* @returns {Boolean|Object}
*/
validate: function(validator, $field, options) {
var value = validator.getFieldValue($field, 'date');
if (value === '') {
return true;
}
options.format = options.format || 'MM/DD/YYYY';
// #683: Force the format to YYYY-MM-DD as the default browser behaviour when using type="date" attribute
if ($field.attr('type') === 'date') {
options.format = 'YYYY-MM-DD';
}
var locale = validator.getLocale(),
message = options.message || FormValidation.I18n[locale].date['default'],
formats = options.format.split(' '),
dateFormat = formats[0],
timeFormat = (formats.length > 1) ? formats[1] : null,
amOrPm = (formats.length > 2) ? formats[2] : null,
sections = value.split(' '),
date = sections[0],
time = (sections.length > 1) ? sections[1] : null;
if (formats.length !== sections.length) {
return {
valid: false,
message: message
};
}
// Determine the separator
var separator = options.separator;
if (!separator) {
separator = (date.indexOf('/') !== -1)
? '/'
: ((date.indexOf('-') !== -1) ? '-' : ((date.indexOf('.') !== -1) ? '.' : null));
}
if (separator === null || date.indexOf(separator) === -1) {
return {
valid: false,
message: message
};
}
// Determine the date
date = date.split(separator);
dateFormat = dateFormat.split(separator);
if (date.length !== dateFormat.length) {
return {
valid: false,
message: message
};
}
var year = date[$.inArray('YYYY', dateFormat)],
month = date[$.inArray('MM', dateFormat)],
day = date[$.inArray('DD', dateFormat)];
if (!year || !month || !day || year.length !== 4) {
return {
valid: false,
message: message
};
}
// Determine the time
var minutes = null, hours = null, seconds = null;
if (timeFormat) {
timeFormat = timeFormat.split(':');
time = time.split(':');
if (timeFormat.length !== time.length) {
return {
valid: false,
message: message
};
}
hours = time.length > 0 ? time[0] : null;
minutes = time.length > 1 ? time[1] : null;
seconds = time.length > 2 ? time[2] : null;
if (hours === '' || minutes === '' || seconds === '') {
return {
valid: false,
message: message
};
}
// Validate seconds
if (seconds) {
if (isNaN(seconds) || seconds.length > 2) {
return {
valid: false,
message: message
};
}
seconds = parseInt(seconds, 10);
if (seconds < 0 || seconds > 60) {
return {
valid: false,
message: message
};
}
}
// Validate hours
if (hours) {
if (isNaN(hours) || hours.length > 2) {
return {
valid: false,
message: message
};
}
hours = parseInt(hours, 10);
if (hours < 0 || hours >= 24 || (amOrPm && hours > 12)) {
return {
valid: false,
message: message
};
}
}
// Validate minutes
if (minutes) {
if (isNaN(minutes) || minutes.length > 2) {
return {
valid: false,
message: message
};
}
minutes = parseInt(minutes, 10);
if (minutes < 0 || minutes > 59) {
return {
valid: false,
message: message
};
}
}
}
// Validate day, month, and year
var valid = FormValidation.Helper.date(year, month, day),
// declare the date, min and max objects
min = null,
max = null,
minOption = options.min,
maxOption = options.max;
if (minOption) {
if (isNaN(Date.parse(minOption))) {
minOption = validator.getDynamicOption($field, minOption);
}
min = minOption instanceof Date ? minOption : this._parseDate(minOption, dateFormat, separator);
// In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
minOption = minOption instanceof Date ? this._formatDate(minOption, options.format) : minOption;
}
if (maxOption) {
if (isNaN(Date.parse(maxOption))) {
maxOption = validator.getDynamicOption($field, maxOption);
}
max = maxOption instanceof Date ? maxOption : this._parseDate(maxOption, dateFormat, separator);
// In order to avoid displaying a date string like "Mon Dec 08 2014 19:14:12 GMT+0000 (WET)"
maxOption = maxOption instanceof Date ? this._formatDate(maxOption, options.format) : maxOption;
}
date = new Date(year, month -1, day, hours, minutes, seconds);
switch (true) {
case (minOption && !maxOption && valid):
valid = date.getTime() >= min.getTime();
message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.min, minOption);
break;
case (maxOption && !minOption && valid):
valid = date.getTime() <= max.getTime();
message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.max, maxOption);
break;
case (maxOption && minOption && valid):
valid = date.getTime() <= max.getTime() && date.getTime() >= min.getTime();
message = options.message || FormValidation.Helper.format(FormValidation.I18n[locale].date.range, [minOption, maxOption]);
break;
default:
break;
}
return {
valid: valid,
message: message
};
},
/**
* Return a date object after parsing the date string
*
* @param {String} date The date string to parse
* @param {String} format The date format
* The format can be:
* - date: Consist of DD, MM, YYYY parts which are separated by the separator option
* - date and time:
* The time can consist of h, m, s parts which are separated by :
* @param {String} separator The separator used to separate the date, month, and year
* @returns {Date}
*/
_parseDate: function(date, format, separator) {
var minutes = 0, hours = 0, seconds = 0,
sections = date.split(' '),
dateSection = sections[0],
timeSection = (sections.length > 1) ? sections[1] : null;
dateSection = dateSection.split(separator);
var year = dateSection[$.inArray('YYYY', format)],
month = dateSection[$.inArray('MM', format)],
day = dateSection[$.inArray('DD', format)];
if (timeSection) {
timeSection = timeSection.split(':');
hours = timeSection.length > 0 ? timeSection[0] : null;
minutes = timeSection.length > 1 ? timeSection[1] : null;
seconds = timeSection.length > 2 ? timeSection[2] : null;
}
return new Date(year, month -1, day, hours, minutes, seconds);
},
/**
* Format date
*
* @param {Date} date The date object to format
* @param {String} format The date format
* The format can consist of the following tokens:
* d Day of the month without leading zeros (1 through 31)
* dd Day of the month with leading zeros (01 through 31)
* m Month without leading zeros (1 through 12)
* mm Month with leading zeros (01 through 12)
* yy Last two digits of year (for example: 14)
* yyyy Full four digits of year (for example: 2014)
* h Hours without leading zeros (1 through 12)
* hh Hours with leading zeros (01 through 12)
* H Hours without leading zeros (0 through 23)
* HH Hours with leading zeros (00 through 23)
* M Minutes without leading zeros (0 through 59)
* MM Minutes with leading zeros (00 through 59)
* s Seconds without leading zeros (0 through 59)
* ss Seconds with leading zeros (00 through 59)
* @returns {String}
*/
_formatDate: function(date, format) {
format = format
.replace(/Y/g, 'y')
.replace(/M/g, 'm')
.replace(/D/g, 'd')
.replace(/:m/g, ':M')
.replace(/:mm/g, ':MM')
.replace(/:S/, ':s')
.replace(/:SS/, ':ss');
var replacer = {
d: function(date) {
return date.getDate();
},
dd: function(date) {
var d = date.getDate();
return (d < 10) ? '0' + d : d;
},
m: function(date) {
return date.getMonth() + 1;
},
mm: function(date) {
var m = date.getMonth() + 1;
return m < 10 ? '0' + m : m;
},
yy: function(date) {
return ('' + date.getFullYear()).substr(2);
},
yyyy: function(date) {
return date.getFullYear();
},
h: function(date) {
return date.getHours() % 12 || 12;
},
hh: function(date) {
var h = date.getHours() % 12 || 12;
return h < 10 ? '0' + h : h;
},
H: function(date) {
return date.getHours();
},
HH: function(date) {
var H = date.getHours();
return H < 10 ? '0' + H : H;
},
M: function(date) {
return date.getMinutes();
},
MM: function(date) {
var M = date.getMinutes();
return M < 10 ? '0' + M : M;
},
s: function(date) {
return date.getSeconds();
},
ss: function(date) {
var s = date.getSeconds();
return s < 10 ? '0' + s : s;
}
};
return format.replace(/d{1,4}|m{1,4}|yy(?:yy)?|([HhMs])\1?|"[^"]*"|'[^']*'/g, function(match) {
return replacer[match] ? replacer[match](date) : match.slice(1, match.length - 1);
});
}
};
}(jQuery));