Unobtrusive validation in Chrome won't validate with dd/mm/yyyy
I'm trying to use the simplest possible scenario using a date picker in different browsers. I suspect I'm doing something very simple the wrong way but after lots of searching around I still haven't found a solution. Below is some sample code that represents what I'm attempting.
If I use Chrome (v12.0.742.122) and pick a date from the picker like 13/08/2011 the jQue开发者_StackOverflow中文版ry validation logic will not allow the page to submit even though I've explicitly specified the format as 'dd/mm/yy'.
If I change the format to 'dd/M/yy' and choose a date like 13/Aug/2011 it works in Chrome but then won't submit for me in IE (v8.0.7600.16385). In FireFox (v3.6.18) both formats work.
What validation script do I need to be able to support date formats of 'dd/mm/yy' in Chrome?
<html>
<head>
<link rel="stylesheet" type="text/css" href="jquery-ui.css" />
<script type="text/javascript" src="jquery-1.4.4.js"></script>
<script type="text/javascript" src="jquery.validate.js"></script>
<script type="text/javascript" src="jquery.validate.unobtrusive.js"></script>
<script type="text/javascript" src="jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('.date').datepicker({ dateFormat: 'dd/mm/yy' });
$.validator.addMethod("dateRule", function(value, element) {
return true;
},
"Error message");
});
</script>
</head>
<body>
<form>
Date: <input type="text" name="myDate" class="date dateRule" />
<input type="submit" />
</form>
</body>
</html>
Four hours later I finally stumbled across the answer. For some reason Chrome seems to have some inbuilt predilection to use US date formats where IE and FireFox are able to be sensible and use the regional settings on the OS.
jQuery.validator.methods["date"] = function (value, element) { return true; }
You can use the Globalize.js plugin available here: https://github.com/jquery/globalize
Then simply redefine the validate method in your web site's main script file like so (avoid editing the jquery.validate.js library file as you may want to update it in future):
$.validator.methods.date = function (value, element) {
return this.optional(element) || Globalize.parseDate(value, "d/M/y", "en");
}
I know I'm a bit late to the party, but here's the solution I used to Chrome validation not accepting UK format dates. A simple plug and play validation, it doesn't rely on any plugins or modifying any files. It will accept any date between 1/1/1900 and 31/31/2999, so US or UK format. Obviously there are invalid dates that will sneak past, but you can tweak the regex to your heart's content. This met my needs as it will be used on a low traffic area of the site, with server-side validation. The area of the site in question is built with ASP.net MVC.
jQuery.validator.methods.date = function(value, element) {
var dateRegex = /^(0?[1-9]\/|[12]\d\/|3[01]\/){2}(19|20)\d\d$/;
return this.optional(element) || dateRegex.test(value);
};
Looks like this issue has been raised with the JQuery team.
https://github.com/jzaefferer/jquery-validation/issues/153
Looks like the workaround for now is to use dateITA in additional-methods.js
It looks like this:
jQuery.validator.addMethod(
"dateITA",
function(value, element) {
var check = false;
var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
if( re.test(value)){
var adata = value.split('/');
var gg = parseInt(adata[0],10);
var mm = parseInt(adata[1],10);
var aaaa = parseInt(adata[2],10);
var xdata = new Date(aaaa,mm-1,gg);
if ( ( xdata.getFullYear() == aaaa )
&& ( xdata.getMonth () == mm - 1 )
&& ( xdata.getDate() == gg ) )
check = true;
else
check = false;
} else
check = false;
return this.optional(element) || check;
},
"Please enter a correct date"
);
If you add that validator you can then attach your datepicker to the '.dateITA' class.
Thus far this has worked well for me to get me beyond this stupid issue in Chrome.
This remains a problem in .net mvc4, where the EditorFor
DateTime
still produces a data-val-date
attribute, despite clear documentation in the jQuery validation plugin not to use it!!! Hopefully microsoft fixes this and data-val-date
is never heard of again!
In the meantime you could use the suggested library via modernizr:
yepnope({
test: isNaN(Date.parse("23/2/2012")),
nope: 'http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.min.js',
complete: function () {
$.validator.methods.date = $.validator.methods.dateITA
}
});
or if not wanting to use yepnope/modernizr, and to get rid of the UTC component of the dateITA method (if using this library to enter a local time, dates will not always validate on the 1st or last day of the month unless on the Greenwich line - i.e. UTC +0):
(function ($) {
var invokeTestDate = function () {
return $.validator.methods.date.call({
optional: function () {
return false;
}, (new Date(2012,8,23)).toLocaleDateString(), null);
};
if (invokeTestDate()) {
return;
}
// http://docs.jquery.com/Plugins/Validation/Methods/date
$.validator.methods.date = function (value, element) {
//ES - Chrome does not use the locale when new Date objects instantiated:
//return this.optional(element) || !/Invalid|NaN/.test(new Date(value));
var d = new Date();
return this.optional(element) || !/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
}
})(jQuery);
I found the simplest correction of this error to be the following code snippet after calling your validation file;
jQuery.validator.methods["date"] = function (value, element){
var shortDateFormat = "dd/mm/yy";
var res = true;
try {
$.datepicker.parseDate(shortDateFormat, value);
} catch (error) {
res = false;
}
return res;
}
Even in versions found in 2016 im still having this issue without the above code in Chrome and not Firefox.
This is my preferred solution as it does not require any additional libraries or plugins to work.
I found this code snippet while googling the issue here.
We use the following to work on our projects;
if ($.validator) {
$.validator.addMethod("date",
function (value, element, params) {
if (this.optional(element)) {
return true;
}
var ok = true;
try {
$.datepicker.parseDate("dd/mm/yy", value);
}
catch (err) {
ok = false;
}
return ok;
});
}
May this code help you.
$.validator.addMethod(
"date",
function(value, element) {
var check = false;
var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/;
var reBR = /^\d{4}\-\d{1,2}\-\d{1,2}$/;
if( re.test(value)){
var adata = value.split('/');
var gg = parseInt(adata[0],10);
var mm = parseInt(adata[1],10);
var aaaa = parseInt(adata[2],10);
var xdata = new Date(aaaa,mm-1,gg);
if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
check = true;
else
check = false;
} else if( reBR.test(value)){
var adata = value.split('-');
var aaaa = parseInt(adata[0],10);
var mm = parseInt(adata[1],10);
var gg = parseInt(adata[2],10);
var xdata = new Date(aaaa,mm-1,gg);
if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) )
check = true;
else
check = false;
} else
check = false;
console.log(check);
return this.optional(element) || check;
},
"Por favor insira uma data válida"
);
should change the dateRule method you define in validate to (the regex is just a simple one for example):
$.validator.addMethod(
"dateRule",
function(value, element) {
return value.match(/^\d\d?\/\d\d?\/\d\d$/);
},
"Please enter a date in the format dd/mm/yy"
);
you can switch the regex for whatever you wish. I got this regex for date from here which supports M/D/YY or M/D/YYYY or MM/DD/YYYY or MM/DD/YY: 1/1/1920 through 12/31/2019; Feb 29 and 30 always allowed
^((0?[13578]|10|12)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[01]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1}))|(0?[2469]|11)(-|\/)(([1-9])|(0[1-9])|([12])([0-9]?)|(3[0]?))(-|\/)((19)([2-9])(\d{1})|(20)([01])(\d{1})|([8901])(\d{1})))$
I also found a solution that appears to work for any culture.
http://devdens.blogspot.com/2011/11/jquery-validation-fix-for-date-format_29.html
It requires you to modify the actual jquery.valdiation.min.js file, but so far it's working for me.
This is the only solution that worked for me: http://www.codeproject.com/Tips/579279/Fixing-jQuery-non-US-Date-Validation-for-Chrome
jQuery.extend(jQuery.validator.methods, {
date: function (value, element) {
var isChrome = window.chrome;
// make correction for chrome
if (isChrome) {
var d = new Date();
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(d.toLocaleDateString(value)));
}
// leave default behavior
else {
return this.optional(element) ||
!/Invalid|NaN/.test(new Date(value));
}
}
});
Or we might try to overwrite the validator instead of ignoring it.
$.validator.addMethod("date", function (value, element) {
var result = true;
try {
$.datepicker.parseDate('dd/mm/yy', value);
}
catch (err) {
result = false;
}
return result;
});
精彩评论