Date of Birth validation keeps showing
Solution 1:
The reason for the client side validation is that the jquery.validate.js
plugin used by jquery.validate.unobtrusive.js
validates dates based on MM/dd/yyyy
format and your entering dates based on a dd/MM/yyyy
format.
The specific code used in jquery.validate.js
for validation is
date: function(value, element) {
return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
}
which depending on the browser your using will give different results (in Chrome, new Date('22/12/1986')
returns Invalid Date
but in FireFox it returns 1987-10-11T13:30:00.000Z
which is valid, just not the date you entered)
You need to override the $.validator
to format dates in your culture. One option is to use the jquery.globalize plugin.
Alternatively you can write your own script. Note that the following script is taken from my own plugin used in conjunction with a @Html.DatePickerFor()
extension method that generates a datepicker. The extension method adds html attributes for the date format based on the server culture and is read with the var format = regex.exec(this.inputFormat);
line of code that I have commented out and replaced with your hard coded format. If you only ever want the dd/MM/yyyy
format, then the script can be simplified because you only need the 'little-endian' format
<script type="text/javascript">
// Override default date validator format to allow culture specific format
$.validator.methods.date = function (value, element) {
return this.optional(element) || globalDate(value).isValid();
};
globalDate = function (value) {
// Initialise a new date
var date = new Date(0);
if (value == undefined) {
// Return todays date
return date;
}
// Get the components of the format
// The separator can be forward slash, hyphen, dot and/or space
var regex = new RegExp(/([dMy]+)([\s/.-]+)([dMy]+)([\s/.-]+)([dMy]+)/);
//------------- see notes above
//var format = regex.exec(this.inputFormat);
var format = regex.exec('dd/MM/yyyy');
//-------------
// Get the components of the value
regex = new RegExp(/(\d+)([\s/.-]+)(\d+)([\s/.-]+)(\d+)/);
value = regex.exec(value);
// Check the value is valid
if (value === null || value[2] !== format[2] || value[4] !== format[4]) {
// Its not valid
date.setTime(Number.NaN);
return date;
}
// TODO: What if year entered as 2 digits?
var day = Number.NaN;
var month = Number.NaN;
var year = Number.NAN;
if (format[1].charAt(0) === 'd') {
// little-endian (day, month, year)
day = parseInt(value[1]);
month = parseInt(value[3]) - 1;
year = parseInt(value[5]);
} else if (format[1].charAt(0) === 'M') {
// middle-endian (month, day, year)
day = parseInt(value[3]);
month = parseInt(value[1]) - 1;
year = parseInt(value[5]);
} else {
// big endian (year, month, day)
day = parseInt(value[5]);
month = parseInt(value[3]) - 1;
year = parseInt(value[1]);
}
date.setFullYear(year);
date.setMonth(month);
date.setDate(day);
// Check its valid
if (date.getDate() !== day || date.getMonth() !== month || date.getFullYear() !== year) {
date.setTime(Number.NaN);
return date;
}
return date;
}
// Methods
Date.prototype.isValid = function () {
return !isNaN(this.getTime());
}
</script>
Side note: Your [RegularExpression]
attribute does nothing and can be removed.