ReBuildAll
LenardG's thoughts (mostly) on .NET development

jQuery validate and the comma decimal separator   (MVC)   
In response to the comments I have received to the original article, I have updated it with information how to modify the behavior of the jQuery validator plugin without directly editing the source.

While working with MVC 3, I hit some problems with validation. MVC 3 uses jQuery validation plugin with unobtrusive validation to help you out. Except when I had to use Finnish formatted numbers, there was a problem. jQuery/javascript did not really like the comma as a decimal separator.

A similar problem is with the range validation, which also refuses to work when using a comma as the decimal separator.

A rather nasty set of problems I might say, especially since number validation rules are added AUTOMATICALLY by ASP.NET MVC if you render a TextBox for a Decimal field in the model. It just seems the writer of the validator plugin forgot about everyone outside US (thanks @Deef for this last comment).

Fixing jquery.validate.js

You can of course go into the source of the validator javascript file and make your changes there, but modifying this file should never be done directly. That would create all kinds of nasty problems when updating to future versions.

Instead, one should take advantage of extending (replacing) the validator functions that are provided by jQuery Validate. (thanks to @ruben for the information on this).

To fix these problems, we can take the default implementation from the jquery.validate.js file for the range() and number() functions. We then create another .js file (say jQueryFixes.js), in which we override these default functions with ones that contain support for the comma as a decimal separator. The contents of the file should be something like this:

$.validator.methods.range = function (value, element, param) {
    var globalizedValue = value.replace(",", ".");
    return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
}

$.validator.methods.number = function (value, element) {
    return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}


This should be the last .js file you include, so it overrides the behavior of the default functions from the jQuery Validator plugin.

For number validation, what we have done is replace the last dot with an expression that also accepts a comma (change is bolded):

return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:[\.,]\d+)?$/.test(value);

This will solve the number validation problem with the decimal point/comma. If you are dealing with thousand separator, you might need to tweak this further.

As for the range validation, I opted to simply replace the comma with a dot, and proceed normally from there on. You could of course use the jquery globalization plugin, please see the comments section for @ruben's recommendation on that one.

And that is about it. Now decimal separator commas should also be accepted by the validators.

 

Comments

Re: jQuery validate and the comma decimal separator
Beautifull
Re: jQuery validate and the comma decimal separator
Thanks a lot Lenard!

simple and efective solution :)
Lenard Gunda Re: jQuery validate and the comma decimal separator
Andrew, this is an old article. I think I looked at some sort of Globalization support back when I originally wrote it, but did not find it good enough / mature enough. Two years is a long time, I am glad to see better support is now available! Thanks for the contribution. I like how you wrapped the original validators.

I still think this should be wrapped into a plugin or something, so you could just drop it in, and you wouldn't have to manually start registering new validators with globalization support.

Andrew Gunn Re: jQuery validate and the comma decimal separator
What about the following; proxy both number and range functions and parse value using Globalize (https://github.com/jquery/globalize)...

var _number = $.validator.methods.number;

$.validator.methods.number = function (value, element) {
return _number.call(this, Globalize.parseFloat(value), element);
};

var _range = $.validator.methods.range;

$.validator.methods.range = function (value, element, param) {
return _range.call(this, Globalize.parseFloat(value), element, param);
};
Re: jQuery validate and the comma decimal separator
Thank you man!
Re: jQuery validate and the comma decimal separator
Damn you saved me some time.
Ty
thanasis Re: jQuery validate and the comma decimal separator
Thanks dude!!
Simone Re: jQuery validate and the comma decimal separator
It's Perfect!!!


Thanks!
Re: jQuery validate and the comma decimal separator
Thank you! I've been searching for a solution, but none worked, except yours. Thank you again!
Lenard Gunda Re: jQuery validate and the comma decimal separator
To all who thanked me: glad to help.

It is true, that maybe my solution is not ideal. Maybe you should detect the culture setting of the user and use validation that matches that culture setting. Often however, clients want their web application to use a particular culture ALWAYS. When in Finland we have to use the comma in decimal values, regardless of the browser settings of the user. Is this a good idea? I'll let everyone answer that for themselves :)

As a side note, the truth is that software by default is often poorly localized or support for localization is often lacking. That's just my two cents.
Fernando Re: jQuery validate and the comma decimal separator
Thanks, it´s works fine for me.
Murali Re: jQuery validate and the comma decimal separator
Instead of changing it you could follow this.

The problem is deal with globalization. So i recommend you to follow Hansleman post http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx
Hocine Re: jQuery validate and the comma decimal separator
the method to fix the problem with MVC4 :

In the jquery.validate.js, find range: function et number: function and replace like that :
range: function (value, element, param) {
var globalizedValue = value.replace(",", ".");
return this.optional(element) || (globalizedValue >= param[0] && globalizedValue <= param[1]);
//return this.optional(element) || ( value >= param[0] && value <= param[1] );
}

number: function (value, element) {

// return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);
return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:[\s\.,]\d{3})+)(?:[\.,]\d+)?$/.test(value);
}
KolDand Re: jQuery validate and the comma decimal separator
It worked like a charm, thanks man!
Stefan Re: jQuery validate and the comma decimal separator
Lenard,

This is awsome, I came upon so many different and complicated proposed solutions and I spent two hours before I found your great article. You saved me!
If you ever come to Serbia, I promise you a free beer or rakija(great national drink)!!!

Thanks,
Stefan
Everton Re: jQuery validate and the comma decimal separator
Very nice,
this saved my time!
Thanks.
turkmame Re: jQuery validate and the comma decimal separator
thanks LenardG,this saved my time
Lenard Gunda Re: jQuery validate and the comma decimal separator
It is indeed possible, although I would advise to create a brand new validator class that you can use. I might do a blog post on that actually in the coming days.
runner Re: jQuery validate and the comma decimal separator
is it possible that I can have the currency symbol in a decimal field without the client side validation saying this is not a number

your help is much appreciated
Øyvind Re: jQuery validate and the comma decimal separator
Worked like a charm. Needed the same for the min function, but it was easy to fix given your example.

Thanks a lot.
Lenard Gunda Re: jQuery validate and the comma decimal separator
Alex, are you sure you have included jquery.validate.js (or the .min version) and jquery.validate.unobtrusive.js (or the .min version)? Before you use the code I showed in the article?

In the newer ASP.NET MVC project templates, these files are not included in the _Layouts.cshtml (for Razor) file. Instead, they are referenced from individual .cshtml files when you generate an editor template (or something that required validation)?

If you use the default generated way, you need to add the code in my article AFTER those includes.
Alex Re: jQuery validate and the comma decimal separator
This does not work for me :-(

Get a browser error:
Uncaught TypeError: Cannot read property 'methods' of undefined

Any idea?
Re: jQuery validate and the comma decimal separator
It works!

Thanks ;)
Russel Re: jQuery validate and the comma decimal separator
Thank You Very Very Much!!! I was dying for this....
Excellent Solution...Worked without a glitch !!
Re: jQuery validate and the comma decimal separator
Very usefull thanks
Fran L Re: jQuery validate and the comma decimal separator
Awesome!
It works, thanks Lenard.
Daniel Carvalho Melo Re: jQuery validate and the comma decimal separator
Sensational!

I´m from Brazil and I searched for this kind of solution during a entire day!
I researched for Custom Binding, change the .js manually, change the Decimal fields to String and populate the Decimal on the property´s setter...
I did´t found a globalization version for this js library, so, I think this is the best solution.

At line 4 of the range validation, I suggest another change to solve validation when using "." to thousand separator:
----------
var globalizedValue = value.replace(".", "").replace(",", ".");
----------

And with we associate this with a mask, we have a nice masked and validated number and currency validation:
http://www.jquerypriceformat.com/

Thank you.




Rene Re: jQuery validate and the comma decimal separator
Hi thanks a lot for the article but in my app is not working I am using jQuery Validation Plugin 1.8.0

Do you know how to solve it in this case?
elperucho Re: jQuery validate and the comma decimal separator
Thanks brother
I had two days with the error of the blessed coma.

lol that is the problems of Latin countries. ;-)
Lenard Gunda Re: jQuery validate and the comma decimal separator
Thanks for the comments @Deef, @ruben. I updated the post to reflect this change (and I also updated my code where I used this :) )

@Vince, are you sure you include the correct version of the validate .js file? MVC project template includes both the regular version and the minified version. If you modified the regular version but include the minified version (which is recommended) your modification might not take effect.
Deef Re: jQuery validate and the comma decimal separator
I agree with Ruben, you should not change the original file in this case (or any other for that matter). Very dangerous if you or someone lese upgrades/updates that file later on and forgets about that change.

One thing is obvious, the MVC team 'forgot' about everyone outside the US.
Vince Re: jQuery validate and the comma decimal separator
The validate for comma's doesn't work. I replaced it in the validate javascript and it does not work.
Lenard Gunda Re: jQuery validate and the comma decimal separator
@Leniel Macaferi, glad to help.

@ruben, thanks for the info, I will have to look into that jQuery globalization stuff. I know I should not modify the .js files directly, but I was in a hurry and did not find anything useful fast enough. Documentation is very much missing IMHO :)
ruben Re: jQuery validate and the comma decimal separator
Much better is to use jquery globalization in this case 2 files are need:(jquery.global.js and jquery.glob.pt-BR.js).Then all you need is this code in your page:

//Function which validates range
$.validator.methods.range = function (value, element, param) {
var newValue = value;

return ($.global.format(newValue, 'n') >= $.global.format(param[0], 'n') && $.global.format(newValue, 'n') <= $.global.format(param[1], 'n'));
}




ruben Re: jQuery validate and the comma decimal separator
There is a little mistake...You shouldnt change the original code of jquery.validate file.Much better is to add follow code to your page,which replace validator methods of jquery.validate:

$.validator.methods.range = function (value, element, param) {
var newValue = value;
for (var i = 0; i < value.length; i++) {
if (value.charAt(i) == ',') {
newValue = value.replace(',', '.');
break;
}
}
return (newValue >= param[0] && newValue <= param[1]);
}

Leniel Macaferi Re: jQuery validate and the comma decimal separator
Hi Lenard,

I faced the same problem here in Brazil where we use ( , ) as a decimal separator.

Thanks for sharing this useful info that helped me to fix the problem.

Regards,

Leniel
Lenard Gunda Re: jQuery validate and the comma decimal separator
Thanks Ricardo, I fixed the typo.
Ricardo Maroquio Re: jQuery validate and the comma decimal separator
There is a small error in the code...
The line 4 of the range fix must be:
var globalizedValue = value.replace(",", ".");
[]s!
Ricardo Maroquio Re: jQuery validate and the comma decimal separator
Very nice, Lenard!
Thanx!