问题与小数,逗号和客户端验证 [英] Issue with Decimals, Commas and Client-Side Validation

查看:103
本文介绍了问题与小数,逗号和客户端验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现客户端验证一个可空<十进制> 的小数点分隔符可以是逗号(例如:123,45)。

I'm trying to achieve client-side validation for a nullable<decimal> whose decimal separator can be a comma (e.g.: 123,45).

在我的观点:

...

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

...

@section Scripts {

   @Styles.Render("~/Content/themes/base/css")
   @Scripts.Render("~/bundles/jquery")
   @Scripts.Render("~/bundles/jqueryui")
   @Scripts.Render("~/bundles/jqueryval")
   @Scripts.Render("~/bundles/jQueryFixes")
   ...scripts for this view...
}

我jQueryFixes覆盖 jquery.validate.js 文件的范围()号()

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

...的建议中对这一问题(如许多岗位/问题:这里这里)。

奇怪的是:

当我尝试提交这样的值,123,45,即使我已经调试与Firebug的剧本,看到我压倒函数被调用和返回true,我不能够提交表单。相反,我对十进制值EditorFor正集中无论出于何种原因,似乎我无法找出原因。

When I try to submit a value such as 123,45, and even though I've debugged the script with Firebug and seen that my overrode functions are being called and returning true, I'm not being able to submit the form. Instead, my EditorFor for the decimal value is being focused for whatever reason and I can't seem to find out why.

(我相信我的服务器端验证 - 使用自定义的粘结剂等 - 工作正常,并且在这里不是问题:我想就如何获取表单一些帮助提交或为什么输入字段越来越集中,即使它看起来有效。)

(I believe that my server-side validation - using a custom binder, etc. - is working fine and that is not the issue here: I would like some help on how to get the form to submit or why is the input field getting focused even though it looks valid.)

编辑1:

附加信息。在我的BundlesConfig.cs:

Additional info. In my BundlesConfig.cs:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));
...
bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
                    "~/Scripts/jquery-ui-{version}.js"));
bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.unobtrusive*",
                    "~/Scripts/jquery.validate*"));
bundles.Add(new ScriptBundle("~/bundles/jQueryFixes").Include(
                    "~/Scripts/jQueryFixes.js")); 
...

编辑2:

@LeftyX的建议后,我尝试使用脚本全球化时代(删除我的jQueryFixes.js后):

After @LeftyX suggestion, I tried using the Globalize script (after removing my jQueryFixes.js):

<script type="text/javascript">
    ...

    $( document ).ready(function() {
        Globalize.culture("en-US", "pt-PT");
    });

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

    //Fix the range to use globalized methods
    jQuery.extend(jQuery.validator.methods, {
        range: function (value, element, param) {
            var val = Globalize.parseFloat(value);
            return this.optional(element) || (val >= param[0] && val <= param[1]);
        }
    });

   ...
</script>

...但我仍然面临着同样的问题: validator.methods.number 将返回true,但形式不提交,输入字段被关注,而不是

...but I still face the same issue: the validator.methods.number is returning true but the form isn't submitted and the input field gets focused instead.

如果我检查输入的元素,而我提出的,我可以看到它迅速从进入类=有效类='输入-validation错误然后再返回到有效。很奇怪的。

If I inspect the input element while I submit, I can see that it quickly goes from class="valid" to class='input-validation-error' and then back to valid. Very strange.

结论:

@LeftyX给了谁发现了同样的问题一个很好的和完整的解决方案。

@LeftyX gave a very good and complete solution for whoever finds the same issues.

我已经拥有可空小数的自定义模型绑定,但全球化的脚本,并在模型中包括文化/视图模型肯定就派上用场了。

I already had a custom model binder for the nullable decimals, but the globalization script and including the culture in the Model/ViewModel sure comes in handy.

另一个原因,我的问题可能包括两次一些脚本的事实,我是(不小心)。

Another reason for my problem could be the fact that I was (accidentally) including some scripts twice.

UPDATE(月/ 2015):

globalize.js 现在是一个有点不同。参考。到<一个href=\"http://stackoverflow.com/questions/20263762/issue-with-decimals-commas-and-client-side-validation/31263906#31263906\">this回答和为更新的步骤文档

globalize.js is a bit different now. Ref. to this answer and the documentation for the updated steps.

推荐答案

我挣扎着相当多与此有关。

I've struggled quite a bit with this.

对我来说,最好的方法是定义一个小数定制绑定:

The best approach for me is to define a custom binder for decimals:

public class DecimalModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext,
        ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider
            .GetValue(bindingContext.ModelName);
        ModelState modelState = new ModelState { Value = valueResult };
        object actualValue = null;
        try
        {
            //Check if this is a nullable decimal and a null or empty string has been passed
            var isNullableAndNull = (bindingContext.ModelMetadata.IsNullableValueType &&
                                     string.IsNullOrEmpty(valueResult.AttemptedValue));

            //If not nullable and null then we should try and parse the decimal
            if (!isNullableAndNull)
            {
                actualValue = Convert.ToDecimal(valueResult.AttemptedValue, CultureInfo.CurrentCulture);
            }
        }
        catch (FormatException e)
        {
            modelState.Errors.Add(e);
        }

        bindingContext.ModelState.Add(bindingContext.ModelName, modelState);
        return actualValue;
    }
}

和在其绑定在的Application_Start 的Global.asax

ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());

我也用在全球化脚本(与文化),它可以在这里找到 或下载的NuGet的>

您bundle应该是这个样子:

Your bundle should look something like this:

bundles.Add(ScriptBundle("~/bundles/jquery").Include(
    "~/Scripts/jquery-{version}.js",
    "~/Scripts/globalize.js",
    "~/Scripts/cultures/globalize.culture.en-GB.js",
    "~/Scripts/cultures/globalize.culture.it-IT.js"
    ));

当然,如果你想支持不同的本地化,你可以添加更多的culures。

现在,当你的DOM就绪(JavaScript的),你可以定义你的文化:

Now, when your DOM is ready (javascript) you can define your culture:

Globalize.culture('en-GB');

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

//Fix the range to use globalized methods
jQuery.extend(jQuery.validator.methods, {
    range: function (value, element, param) {
    var val = Globalize.parseFloat(value);
    return this.optional(element) || (val >= param[0] && val <= param[1]);
    }
});

$.validator.methods.date = function (value, element) {
    return (this.optional(element) || Globalize.parseDate(value));
}

和自定​​义验证(我已经添加了日期为好)。你这样做在你的 jQueryFixes

and customize your validations (I've added the date as well). You've done that in your jQueryFixes.

您可以在这里找到工作的例子(MvcAppForDecimals),您可以更改语言
使用工具栏和饼干,这样的文化可以在服务器上发生变化。

You can find a working example here (MvcAppForDecimals) where you can change languages using a toolbar and cookies so that the culture can change on the server as well.

在例子中,我读的Application_BeginRequest 饼干或使用默认文化定义在web.config:

In the example I read the cookie in Application_BeginRequest or use the default culture define in the web.config:

<globalization enableClientBasedCulture="true" uiCulture="en-GB" culture="en-GB" />

我还定义了一个ActionFilter(LanguageFilterAttribute),一个注入在基本视图模型目前的文化,使客户使用服务器端的当前设置。

I've also defined a ActionFilter (LanguageFilterAttribute) which injects the current culture in a base viewmodel so the client uses the current set on the server side.

这是扩展的解释可以发现<一个href=\"http://www.hanselman.com/blog/GlobalizationInternationalizationAndLocalizationInASPNETMVC3JavaScriptAndJQueryPart1.aspx\">here.

An extended explanation can be found here.

关于在全球化脚本和文化的一些更多的信息设置这里

Some more info about the globalize script and culture settings here.

这篇关于问题与小数,逗号和客户端验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆