MVC/JQuery validation does not accept comma as decimal separator
A more robust solution might be to wrap the validator methods in your own function which converts your comma separated number to one that is decimal separated.
One trick is to use .call to call the original validator function as if "this" was the original this that the developers thought (e.g. they use a function "this.optional" for their step validation).
var originalNumber = $.validator.methods.number;
var wrappedNumber = function (value, element) {
var fixedValue = parseFloat(value.toString().replace(",", "."));
return originalNumber.call($.validator.prototype, fixedValue, element); // Call function as if "this" is the original caller
};
$.validator.methods.number = wrappedNumber;
You could make this work for any validator, e.g. the step validation:
var originalStep = $.validator.methods.step;
var wrappedStep = function (value, element, param) {
var fixedValue = parseFloat(value.toString().replace(",", "."));
return originalStep.call($.validator.prototype, fixedValue, element, param);
};
$.validator.methods.step = wrappedStep;
Even though it was suggested, that this is rather a jQuery problem than an MVC problem, I think it is an MVC Problem.
No that is no correct. You seeing a client side validation error because, by default, jquery.validate.js
(an independent 3rd party plugin not associated with MicroSoft, that MVC uses for client side validation) validates numbers based on the decimal separator being a .
(dot), not a ,
(comma).
MVC is server side code and does not run in the browser. To perform client side validation, MVC's HtmlHelper
methods that generate form controls render a set of data-val-*
attributes in the html used to describe the validation to be performed, which are in turn parsed by the jquery.validate.unobtrusive.js
plugin when the DOM is loaded, and uses those to add rules to the $.validator
.
In the case of your double
property it will add a data-val-number
attribute (in addition to data-val-required
attribute), which will add the number
rule which is defined as
// http://docs.jquery.com/Plugins/Validation/Methods/number
number: function( value, element ) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
},
where the decimal separator is a dot, and the thousands separator is a comma (presumably because the plugin was developed in the US, so uses a US format).
You need to overwrite the default behavior which you can do by using plugins such as jquery.globalize, or including the following script (note the regex just swaps the dot and comma)
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:\.\d{3})+)?(?:,\d+)?$/.test(value);
}
Note the above script needs to be after the jquery.validate.js
script but not wrapped in $(document).ready()
What links it to MVC for me, is the fact that I can solve the date validation problem by adding the line
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:yyyy-MM-dd}")]
to the model.
Its actually your [DataType(DataType.Date)]
attribute in conjunction with the [DisplayFormat]
attribute that is influencing the html that is generated. The [DataType]
attribute generates <input type="date" ... />
which in turn renders the browsers HTML-5 datepicker if the browser supports it. In accordance with the specifications the format must be yyyy-MM-dd
(ISO format) hence the need for the [DisplayFormat]
attribute as well.
The HTML-5 datepicker renders the date in the browsers culture. The image you have shown where the input is 26.1.2018
is because your browser culture is de-DE
, but if I navigated to your site, I would see 26/1/2018
in the input because my culture is en-AU
(Australian), and if a United States user navigated to your site, they would see 1/26/2018
.
The reason client side validation works for the date property is that the jquery.validate.js
plugin includes date rules for both US format (MM/dd/yyyy
) and ISO format (yyyy-MM-dd
).
And if you were to use @Html.TextBoxFor(m => m.Inbetriebnahmedatum)
(which ignores your [DataType]
and [DisplayFormat]
attributes), and entered 26.1.2018
in the input, you would also see a client side validation error.
I think the problem is jquery validator i'v used thus for resolve the comma/point error
$.validator.methods.number = function (value, element) {
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
just try play with it