Date of Birth validation keeps showing
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.
Date of birth validation: How far/much would you go?
Think about the times you've filled out forms. How many times have you been frustrated because some "overly clever" programmer inserted some "validation" that just happened to be incorrect for your circumstance? I say, trust the user. Come to think of it, as time goes on I guess people are living longer and getting on the net at earlier ages, anyway. :P
Validate date of birth greater than today?
What I understand from your question is - "Before posting the form, you'd like to check if the DOB field has a date that must not be greater than today's date.". If this is correct, then try this, Hope this help -
<script type="text/javascript">
function checkDOB() {
var dateString = document.getElementById('id_dateOfBirth').value;
var myDate = new Date(dateString);
var today = new Date();
if ( myDate > today ) {
$('#id_dateOfBirth').after('<p>You cannot enter a date in the future!.</p>');
return false;
}
return true;
}
</script>
How to validate a user's birth date in JavaScript with a Regular Expression?
There are several issues:
- You pass a Date to the regex
test
method, but you should really pass the input string. - Several variables are not defined, including
result
,birthday
,todayYear
. - The cutoff points seem to be defined as numbers (number of years), but in the
if
conditions they are treated as dates. This cannot work. You should really subtract a number of years from the current date (resulting in a date). Just comparing calendar years is not a right method to determine someone's age. At the time of writing, someone born in January 2000 is older than 19, while someone born in December 2000 is younger than 19. - An error message saying that the date is not a number is misleading to the user who had entered "13/13/1990". It should just say the date is invalid.
- The regex should require that the input does not contain other things than just the date -- it should use
^
and$
anchors - The dd/mm/yyyy format is ambiguous. When passed to
new Date
, it will be interpreted as mm/dd/yyyy. Better first convert it to some standard format like YYYY-MM-DD. The code below does this conversion of the dd/mm/yyyy input to the YYYY-MM-DD format, before passing it to theDate
constructor.
Also, since there is nothing dynamic in your regex, you can just use a regex literal, instead of calling the RegExp
constructor.
Here is the corrected code:
function myValidator() { var birthday = document.getElementById("dob").value; // Don't get Date yet... var regexVar = /^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/; // add anchors; use literal var regexVarTest = regexVar.test(birthday); // pass the string, not the Date var userBirthDate = new Date(birthday.replace(regexVar, "$3-$2-$1")); // Use YYYY-MM-DD format var todayYear = (new Date()).getFullYear(); // Always use FullYear!! var cutOff19 = new Date(); // should be a Date cutOff19.setFullYear(todayYear - 19); // ... var cutOff95 = new Date(); cutOff95.setFullYear(todayYear - 95); if (!regexVarTest) { // Test this before the other tests dobErrMsg.innerHTML = "enter date of birth as dd/mm/yyyy"; } else if (isNaN(userBirthDate)) { dobErrMsg.innerHTML = "date of birth is invalid"; } else if (userBirthDate > cutOff19) { dobErrMsg.innerHTML = "you have to be older than 19"; } else if (userBirthDate < cutOff95) { dobErrMsg.innerHTML = "you have to be younger than 95"; } else { dobErrMsg.innerHTML = ""; } return userBirthDate; // Return the date instead of an undefined variable}
<p> <label for="dob">Date of Birth</label> <input type="text" name="dob" id="dob" maxlength="10" placeholder="dd/mm/yyyy" pattern="([0-9]{2})\/([0-9]{2})\/([0-9]{4})" required="required" /> <span id="dobErrMsg"></span></p><button onclick="myValidator()">Run validation</button>
Related Topics
How to Disable a System Device Programmatically
Accessing UI Control from Backgroundworker Thread
Is There a Bigfloat Class in C#
Dynamic Routes from Database for ASP.NET MVC Cms
How to Save Console.Writeline Output to Text File
How to Do Network Discovery Using Udp Broadcast
Access to Foreach Variable in Closure Warning
How to Check If Two Expression<Func<T, Bool>> Are the Same
Razor: Declarative HTML Helpers
Does .Net Ftpwebrequest Support Both Implicit (Ftps) and Explicit (Ftpes)
I Didn't Find "Zipfile" Class in the "System.Io.Compression" Namespace
Binding Listbox to List<Object> in Winforms
How to Return an Anonymous Type from a Method
What's Better: Dataset or Datareader
Check If Instance Is of a Type
What's the Difference Between Application.Run() and Form.Showdialog()