web-dev-qa-db-fra.com

MVC 3 jQuery Validation / globalisation du nombre / champ décimal

Lorsque vous utilisez la mondialisation culture = "da-DK" dans le fichier Web.config, la validation jQuery ne fonctionne pas.

Au Danemark, nous utilisons la notation 19,95 au lieu de la méthode américaine 19,95 lorsque nous écrivons un prix pour un produit, et cela m'a posé un problème que je ne peux pas résoudre.

J'ai démarré VS2010, un nouveau projet MVC 3, ajouté un homeController, une classe Product et une simple vue d'édition standard et l'erreur est déjà là.

Classe de produit:

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);
    }
}

Affichage de l'index:

@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>
}

Le résultat:

Malheureusement, je ne peux pas soumettre d'image ici - veuillez donc suivre ce lien pour voir le résultat: http://www.designvision.dk/temp/mvc3_razor_validation_error.gif

SO - lors de l'exécution du site Web, le champ sera défini sur 19,00 - ce qui IS la définition de culture correcte - mais lors de la tentative d'enregistrement, la validation échoue.

Veuillez aider ...

66
designvision.dk

Vous pouvez essayer le plugin jQuery Globalization de 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>

Le plugin a été renommé et déplacé, vous devez utiliser Globalize (mars 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>

en savoir plus sur article de blog de Scott Hanselman


57
Darin Dimitrov

Script mis à jour pour la version actuelle de https://github.com/jquery/globalize avec prise en charge des éléments facultatifs

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

$(function () {
    Globalize.culture('%%culture%%');
});
23
shatl

@shatl a la bonne réponse dès aujourd'hui. Remarque pour l'attribut range, vous aurez besoin d'un hack illustré ci-dessous. Le code complet à ajouter est indiqué ci-dessous:

@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>
}
14
RickAndMSFT

Juste pour référence future, ce qui a fonctionné pour moi était le suivant:

N'oubliez pas de définir la bonne version de jQuery et la culture correcte, qui dans cet exemple est danoise.
S'il ne peut pas y avoir de points dans la valeur, décommentez le commentaire.

<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>
1
Johnny

J'ai fini par suivre les conseils du blog de Scott Hanselman sur ce sujet - vous pouvez en lire plus ici:

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

J'ai dû faire quelques changements pour utiliser Globalize au lieu de jQuery Global (maintenant jQuery Global est mort). J'ai écrit cela dans le billet de blog suivant au cas où cela serait utile:

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

1
John Reilly

Pas de plugins

Je pense que la façon la plus simple de contourner cela sans aucun plugin est simplement de remplacer la validation par défaut, comme ceci:

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

Si vous regardez le code source de jquery.validate.js vous verrez qu'il teste juste une expression rationnelle comme le code ci-dessus, plus il valide si l'élément est facultatif:

enter image description here

0

je viens d'Argentine et je me bats avec ce problème il y a longtemps, nous utilisons "," comme séparateur décimal, si vous écrivez "virgule", la validation javascript échoue, mais si vous mettez ".", le modèle recevra un nombre traduit en entier (55,60 sera 5560)

J'ai résolu ce problème avec cette solution simple:

1er - J'ai mis à jour les bibliothèques de validation jquery, en utilisant de nouvelles adresses cdn de: http://jqueryvalidation.org/

les liens que j'ai inclus sur mon javascript sont les suivants:

<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>

et si vous le voulez dans une langue spécifique (dans mon cas l'espagnol) ajoutez aussi cette ligne:

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

Remplacez ES par la langue souhaitée.

2e - Si vous souhaitez autoriser la décimale du pavé numérique, vous devez remplacer "." avec "," pour fonctionner correctement, ajoutez ce code à votre page pour le faire automatiquement:

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

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

});

Presto, problème résolu.

Au revoir.

0
Yogurtu

après quelques recherches ... j'ai trouvé une solution.

Web.config dans <system.web> ajouter

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

étendre la classe HtmlHelper

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 à la fin de <head> ajouter

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

Après ces changements, je suis capable de manipuler des nombres décimaux avec mon interface graphique Web.

Cordialement, Giacomo

0
gsscoder

Merci pour cette page, ça m'a sauvé pas mal d'ennuis, j'ai quand même dû réparer le code globaliser. La culture suédoise n'accepte pas le point comme séparateur, mais comme parseFloat utilise les points d'analyse javasacript sous-jacents, ils seront acceptés comme séparateur décimal, mais côté serveur, ceux-ci seront rejetés. Pour résoudre ce problème, je remplace le parseFloat comme ceci

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);
};

J'ai ouvert un ticket à leur Github alors peut-être que ce sera corrigé

0
Anders