Introduction
When using jQuery validation for dates, you will find out that it does not work well for dates using Chrome. This happens when you use a non-US locale.
This tip will provide an example displaying the bug, and another one showing its fix. Both codes are available for download. The one holding the problem is the date_with_bug.html, and one displaying the solution is the date_fixed.html.
Background
This tip is based on the solution presented in the following link: jQuery Date Validation in Chrome. According to this tip, Chrome does not take into account localization when processing dates. The solution presented in the mentioned link, however, does not work when the Operating System is setup to use a non-US locale. This tip does take this into consideration providing the correct solution for all scenarios.
Using the Code
Please do remember that to reproduce the issues in this tip, your Operating System has to be configured to a US-locale.
Displayed below is the code which illustrates the problem. Note that this is a simple form holding an input and a submit button. In the input, the jQuery calendar is attached. Finally observe, as well, that the date input is being validated for the requirements of a mandatory field and a date one.
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="./jquery.validate.min.js"></script>
<script src="./jquery.ui.datepicker-pt-BR.js"></script>
<link rel="stylesheet"
href="http://www.codeproject.com/resources/demos/style.css" />
<script>
$().ready(function() {
$.datepicker.setDefaults($.datepicker.regional["pt-BR"]);
$( "#datepicker" ).datepicker();
$("#dateForm").validate({
rules: {
datepicker: {
required: true,
date: true
}
}
});
});
</script>
</head>
<body>
<form id="dateForm">
<p>Date: <input type="text"
id="datepicker" name="datepicker" /></p>
<p><input type="submit" /></p>
<form>
</body>
</html>
If you open the chrome browser with this source code (leave the JavaScript files in the zipped file where they were so everything works properly) and select the date April, 17, 2013 via jQuery calendar, you will note that the date will be printed as "17/04/2013" which is the pt-br date format, which is the locale setup. Now, try to submit the form by pressing "Submit Query". You will see a message stating the date is invalid.
In order to solve this issue, you should extend jQuery functionality and force date localization for the chrome browser only, as displayed below:
jQuery.extend(jQuery.validator.methods, {
date: function (value, element) {
var isChrome = window.chrome;
if (isChrome) {
var d = new Date();
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
}
else {
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(value));
}
}
});
Adding the code above to the HTML example used in the tutorial, you will have the code displayed below:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>jQuery UI Datepicker - Default functionality</title>
<link rel="stylesheet"
href="http://code.jquery.com/ui/1.10.2/themes/smoothness/jquery-ui.css" />
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="./jquery.validate.min.js"></script>
<script src="./jquery.ui.datepicker-pt-BR.js"></script>
<link rel="stylesheet"
href="http://www.codeproject.com/resources/demos/style.css" />
<script>
$().ready(function() {
jQuery.extend(jQuery.validator.methods, {
date: function (value, element) {
var isChrome = window.chrome;
if (isChrome) {
var d = new Date();
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
}
else {
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(value));
}
}
});
$.datepicker.setDefaults($.datepicker.regional["pt-BR"]);
$( "#datepicker" ).datepicker();
$("#dateForm").validate({
rules: {
datepicker: {
required: true,
date: true
}
}
});
});
</script>
</head>
<body>
<form id="dateForm">
<p>Date: <input type="text"
id="datepicker" name="datepicker" /></p>
<p><input type="submit" /></p>
<form>
</body>
</html>
If you execute the code above selecting again April 17, 2013 and submit the form, you will see that the validation passed as it should have.
Points of Interest
The interesting part of this tip was that the fixing did not involve changing the jQuery source script itself, but extending it. Doing this makes the solution pluggable and much easier to maintain.
History
- Version 1.0: Added initial version of the tip
- Version 2.0: Added fix for the case where the Operating System is configured to a non-US locale