66

When using globalization culture="da-DK" in the Web.config file, the jQuery validation does not work.

In Denmark, we use the notation 19,95 instead of the US way 19.95 when we write a price for at product, and that have given me a problem, that I can't solve.

I've started VS2010, new MVC 3 project, added a homeController, a Product class, and a simple standard edit view and the error is already there.

Product Class:

public class Product
{
    public string name { get; set; }
    public string itemNo { get; set; }
    public decimal price { get; set; }
}

HomeController:

public class homeController : Controller
{
    public ActionResult Index()
    {
        var product1 = new Product { name = "Testproduct", itemNo = "PRD-151541", price = 19 };
        return View(product1);
    }
}

Index View:

@model WebUI.DomainModel.Product

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Product</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.name)
            @Html.ValidationMessageFor(model => model.name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.itemNo)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.itemNo)
            @Html.ValidationMessageFor(model => model.itemNo)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.price)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.price)
            @Html.ValidationMessageFor(model => model.price)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}

The result:

Unfortunately I can't submit an image here - so please follow this link to see the result: http://www.designvision.dk/temp/mvc3_razor_validation_error.gif

SO - when running the website, the field will be set to 19,00 - which IS the correct culture definition - but when trying to save, validation fails.

Please help...

Darko
  • 38,310
  • 15
  • 80
  • 107
designvision.dk
  • 783
  • 1
  • 7
  • 9
  • +1 good question, i have the same problem, just with dates – Darko May 19 '11 at 00:22
  • good question and better if you send this to Microsoft Connect. When a developer generates automatically views based on an entity framework, @Html.ValidationMessageFor for decimal fields behaves exactly like you have shown here. – Junior Mayhé Jan 11 '13 at 17:36

9 Answers9

57

You could try the jQuery Globalization plugin from Microsoft:

<script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

<script src="@Url.Content("~/Scripts/jquery.glob.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/globinfo/jquery.glob.da-dk.js")" type="text/javascript"></script>
<script type="text/javascript">
    $.validator.methods.number = function (value, element) {
        return !isNaN($.parseFloat(value));
    }

    $(function () {
        $.preferCulture('da-DK');
    });
</script>

Plugin was renamed and moved, you should use Globalize (Mar 2012)

<script src="@Url.Content("~/Scripts/jquery.globalize/globalize.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/cultures/globalize.culture.da-DK.js")" type="text/javascript"></script>
<script type="text/javascript">
    $.validator.methods.number = function (value, element) {
        return !isNaN(Globalize.parseFloat(value));
    }

    $(document).ready(function () {
        Globalize.culture('da-DK');
    });
</script>

more about this on Scott Hanselman blog post


rgripper
  • 1,066
  • 15
  • 23
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Ohh, it's really strange - I've been at that site yesterday, and I couldn't get it work. But it is working now - THANKS A LOT! – designvision.dk Mar 05 '11 at 10:39
  • 1
    if value is "0" parseFloat will return 0 that's false. I solved this way $.validator.methods.number = function (value, element) { return parseFloat(value).toString() !== "NaN"; } – Zote Mar 14 '11 at 19:18
  • For the most current version of [jquery globalize](https://github.com/jquery/globalize) code should look like this `$.validator.methods.number = function (value, element) { return !isNaN(Globalize.parseFloat(value)); } $(function () { Globalize.culture('%%culture%%'); });` – shatl Jun 25 '11 at 09:41
  • 6
    Better code to support optional elements `$.validator.methods.number = function (value, element) { return this.optional(element) || !isNaN(Globalize.parseFloat(value)); } $(function () { Globalize.culture('%%culture%%'); });` – shatl Jun 27 '11 at 11:54
  • 3
    Outdated, or at least didn't work for me. See the answer from shatl for an up-to-date version (worked for me). – lko Feb 23 '12 at 11:20
  • @Darin - Why we need to call Globalize.culture('da-DK') inside document ready event? – Freshblood Jun 02 '12 at 20:47
  • 1
    Since the link leads us to https://github.com/jquery/jquery-global/ which has 404 page, we are going to flag this answer. Here are the js files: http://dl.dropbox.com/u/3931391/jQuery%20Globalization%20plugin%20-%20jquery-glob%20-%20jquery-global.rar – Junior Mayhé Jan 11 '13 at 17:41
  • @JuniorMayhé, feel free to edit the answer. I have posted it on the 5th of March 2011 and I hope you realize that it is impossible to keep all the answers up to date all the time. That's why StackOverflow is a community driven website - it allows you to edit and improve the contents of some answers that are no longer relevant. – Darin Dimitrov Jan 11 '13 at 22:16
23

Updated script for current version of https://github.com/jquery/globalize with optional elements support

$.validator.methods.number = function (value, element) {
   return this.optional(element) || !isNaN(Globalize.parseFloat(value));
}

$(function () {
    Globalize.culture('%%culture%%');
});
shatl
  • 911
  • 16
  • 21
14

@shatl has the right answer as of today. Note for the range attribute you'll need a hack shown below. The complete code to add is shown below:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script type="text/javascript" src="~/Scripts/globalize.js"></script>
    <script type="text/javascript" src="~/Scripts/globalize.culture.fr-FR.js"></script>
    <script type="text/javascript">
        $.validator.methods.number = function (value, element) {
            return this.optional(element) ||
                !isNaN(Globalize.parseFloat(value));
        }
        $(document).ready(function () {
            Globalize.culture('fr-FR');
        });

        jQuery.extend(jQuery.validator.methods, {    
            range: function (value, element, param) {        
                //Use the Globalization plugin to parse the value        
                var val = $.global.parseFloat(value);
                return this.optional(element) || (
                    val >= param[0] && val <= param[1]);
            }
        });
    </script>
}
Christopher
  • 2,005
  • 3
  • 24
  • 50
RickAndMSFT
  • 20,912
  • 8
  • 60
  • 78
1

I ended up following the advice in Scott Hanselman's blog on this topic - you can read about this here:

http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx

I had to make some changes to use Globalize instead of jQuery Global (now jQuery Global is dead). I wrote this up in the following blog post in case that's helpful:

http://icanmakethiswork.blogspot.co.uk/2012/09/globalize-and-jquery-validate.html

John Reilly
  • 5,791
  • 5
  • 38
  • 63
1

Just for future reference, what worked for me was the following:

Remember to set the proper jQuery version, and the correct culture, which in this example is danish.
If there can be no periods in the value then uncomment the comment.

<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"
    type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.min.js")"
    type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"
    type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/globalize.js")"
    type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.globalize/cultures/globalize.culture.da-DK.js")"
    type="text/javascript"></script>
<script type="text/javascript">
        $.validator.methods.number = function (value, element) {
            // if (value.indexOf(".") >= 0) {
            //     return false;
            // }
            return (Globalize.parseFloat(value));
        }

        $(document).ready(function () {
            Globalize.culture('da-DK');
        });

        jQuery.extend(jQuery.validator.methods, {
            range: function (value, element, param) {
                //Use the Globalization plugin to parse the value
                var val = Globalize.parseFloat(value);
                return this.optional(element) || (val >= param[0] && val <= param[1]);
            }
        });
</script>
Johnny
  • 785
  • 1
  • 7
  • 16
0

after some research... I found a solution.

Web.config in <system.web> add

<globalization culture="auto" uiCulture="auto" enableClientBasedCulture="true"/>

Extend HtmlHelper class

namespace System.Web.Mvc
{
    public static class LocalizationHelper
    {
        public static IHtmlString MetaAcceptLanguage(this HtmlHelper html)
        {
            var acceptLang = HttpUtility.HtmlAttributeEncode(Thread.CurrentThread.CurrentUICulture.ToString());
            return new HtmlString(string.Format("<meta name=\"accept-language\" content=\"{0}\"/>", acceptLang));
        }
    }
}

_Layout.cshtml at the end of <head> add

@Html.MetaAcceptLanguage();
<script type="text/javascript">
    $(document).ready(function () {
        var data = $("meta[name='accept-language']").attr("content");
        $.global.preferCulture(data);
    });
</script>

After these changes I'm able to manipulate decimal numbers with my web gui.

Regards, Giacomo

gsscoder
  • 3,088
  • 4
  • 33
  • 49
  • 4
    Looks alot like Scott [Hanselsmans solution](http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx). – René Feb 02 '13 at 12:01
  • @René a bit too much like Scott's solution if you ask me. – Jacques Aug 15 '14 at 11:57
0

i'm from argentina, and i'm fighting with this problem a long time ago, we use "," as decimal separator, if you write "comma" javascript validation fails, but if you put ".", model will receibe a number translated to integer (55.60 will be 5560)

I solved out this problem with this simply solution:

1st- I upgraded jquery validation librarys, using new cdn addresses from: http://jqueryvalidation.org/

the links that I included on my javascript are this:

<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/jquery.validate.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/additional-methods.min.js"></script>

and if you want it in a specific language (in my case Spanish) add this line too:

<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.13.0/localization/messages_es.js"></script>

Replace ES with the language you want.

2nd- If you want to allow numeric keypad decimal, you must replace "." with "," to work properly, add this code to your page to do that automatically:

$('#txtCurrency').keyup(function () {

    $('#txtCurrency').val($('#txtCurrency').val().replace(/\./g, ','));

});

Presto, problem solved.

Bye.

Yogurtu
  • 2,656
  • 3
  • 23
  • 23
0

No plugins

I think the easiest way to workaround this without any plugin is by just overriding the default validation, like this:

<script type="text/javascript">
    $.validator.methods.number = function (value, element) {            
        var regex = /^(\d*)(\,\d{1,2})?$/; //99999,99
        return regex.test(value);
    }
</script>

If you look at the source code of jquery.validate.js you will see that it just tests a regex like the code above, plus it validates if the element is optional:

enter image description here

fabriciorissetto
  • 9,475
  • 5
  • 65
  • 73
  • It's not a plugin and will work ins this case. But its an override to the standard validation plugin, while the plugin extends it for a different culture. The extension will also give you correct validation for other types like date, the script will not. – Christoph Brückmann Nov 01 '16 at 16:15
0

Thanks for this page, saved me alot of trouble, I had to fix the globalize code how ever. Swedish culture does not accept dot as seperator, but since parseFloat uses the underlying javasacript parse dots will be accepcted as decimal seperator, but server side these will be rejected. To fix this i override the parseFloat like this

Globalize.orgParaseFloat = Globalize.parseFloat;
Globalize.parseFloat = function(value) {
    var culture = this.findClosestCulture();
    var seperatorFound = false;
    for (var i in culture.numberFormat) {
        if (culture.numberFormat[i] == ".") {
            seperatorFound = true;
        }
    }

    if (!seperatorFound) {
        value = value.replace(".", "NaN");
    }

    return this.orgParaseFloat(value);
};

I've open a ticket at their Github so maybe this will be fixed

Anders
  • 17,306
  • 10
  • 76
  • 144