Javascript 小数、逗号和客户端验证问题
我正在尝试为一个可为null的Javascript 小数、逗号和客户端验证问题,javascript,jquery,validation,asp.net-mvc-4,Javascript,Jquery,Validation,Asp.net Mvc 4,我正在尝试为一个可为null的实现客户端验证,它的十进制分隔符可以是逗号(例如:123,45) 我认为: ... <div class="editor-label"> @Html.LabelFor(model => model.Turnover) </div> <div class="editor-field"> @Html.EditorFor(model => model.Turnover) @Html.Validati
实现客户端验证,它的十进制分隔符可以是逗号(例如: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...
}
…正如许多关于这个问题的帖子/问题所建议的那样(例如:或)
奇怪的是:
当我试图提交一个值,比如123,45,即使我已经用Firebug调试了脚本,并且看到我的overrode函数正在被调用并返回true,我也无法提交表单。相反,无论出于什么原因,我的十进制值编辑器都在关注,我似乎无法找到原因
(我相信我的服务器端验证(使用自定义活页夹等)工作正常,不是这里的问题:我希望获得一些帮助,了解如何提交表单,或者为什么输入字段即使看起来有效,也会变得重点突出。)
编辑1:
其他信息。在my BundleConfig.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建议之后,我尝试使用Globalize脚本(在删除我的jQueryFixes.js之后):
...
$(文档).ready(函数(){
全球化。文化(“en-US”、“pt-pt”);
});
$.validator.methods.number=函数(值,元素){
返回此.optional(element)| | jQuery.isNumeric(Globalize.parseFloat(value));
}
//修正使用全球化方法的范围
extend(jQuery.validator.methods{
范围:函数(值、元素、参数){
var val=Globalize.parseFloat(值);
返回这个。可选的(元素)| |(val>=param[0]&&val我对此做了很多努力
对我来说,最好的方法是为小数定义自定义绑定:
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;
}
}
并将其绑定到全局.asax中的应用程序\u Start
:
ModelBinders.Binders.Add(typeof(decimal), new DecimalModelBinder());
ModelBinders.Binders.Add(typeof(decimal?), new DecimalModelBinder());
我还使用globalize脚本(带有文化),可以从nuget找到或下载该脚本
您的捆绑包应该如下所示:
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"
));
当然,如果您想支持不同的本地化,可以添加更多的文化。
现在,当DOM就绪(javascript)时,您可以定义您的区域性:
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));
}
我还定义了一个ActionFilter(LanguageFilterAttribute),它将当前区域性注入到基本视图模型中,以便客户端使用服务器端的当前集
可以找到扩展的解释
有关全球化脚本和区域性设置的更多信息。只是一个关于全球化脚本和区域性设置的小更新。现在情况有点不同(而且令人困惑):
包括以下脚本:
<!--
First, we load Globalize's dependencies (`cldrjs` and its supplemental
module).
-->
<script type="text/javascript" src="~/Scripts/cldr.js"></script>
<script type="text/javascript" src="~/Scripts/cldr/event.js"></script>
<script type="text/javascript" src="~/Scripts/cldr/supplemental.js"></script>
<!--
Next, we load Globalize and its modules.
-->
<script type="text/javascript" src="~/Scripts/globalize.js"></script>
<script type="text/javascript" src="~/Scripts/globalize/number.js"></script>
在您的Web.config(ASP.NET MVC应用程序)中。嘿,回答得非常好且完整,谢谢。我已经有了DecimalModelBinder,但这不是问题所在,因为我正在努力进行客户端验证(即表单甚至没有提交到服务器,以便ModelBinder可以完成其工作)。虽然我添加了Globalize脚本,但我仍然面临相同的问题:好像验证正在接受值,但其他东西阻止提交。谢谢。问题可能是服务器和客户端使用不同的区域性。Globalize脚本和DecimalModelBinder允许您避免检查逗号或点为小数,但您必须设置要使用的区域性。您可以查看我的示例代码。对于如此简单的事情,这是一项大量的工作!您的工作示例也是一个很大的帮助。谢谢&upvote。@user1987392:很高兴我提供了帮助。干杯。有问题//请修复使用全球化方法的范围。执行此操作后代码,客户端验证无效。浏览器自动将表单提交到服务器而无需客户端验证。我不确定原因。
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));
}
<globalization enableClientBasedCulture="true" uiCulture="en-GB" culture="en-GB" />
<!--
First, we load Globalize's dependencies (`cldrjs` and its supplemental
module).
-->
<script type="text/javascript" src="~/Scripts/cldr.js"></script>
<script type="text/javascript" src="~/Scripts/cldr/event.js"></script>
<script type="text/javascript" src="~/Scripts/cldr/supplemental.js"></script>
<!--
Next, we load Globalize and its modules.
-->
<script type="text/javascript" src="~/Scripts/globalize.js"></script>
<script type="text/javascript" src="~/Scripts/globalize/number.js"></script>
<script type='text/javascript'>
// At this point, we have Globalize loaded. But, before we can use it, we
// need to feed it on the appropriate I18n content (Unicode CLDR). In order
// to do so, we use `Globalize.load()` and pass the content.
$.when($.getJSON('/Scripts/cldr/supplemental/likelySubtags.json'),
$.getJSON('/Scripts/cldr/main/en-GB/numbers.json'),
...other locales...
$.getJSON('/Scripts/cldr/supplemental/numberingSystems.json'))
.done(function (result1, result2, result3, result4) {
Globalize.load(result1[0]); //contains data of first executed request
...load the other ones...
Globalize.load(result3[0]); //contains data of third executed request
Globalize.load(result4[0]); //contains data of fourth executed request
var glob = Globalize([YOUR-LOCALE]); // e.g. en-UK, pt-PT, pt-BR, es-ES, etc.
$.validator.methods.number = function (value, element) {
var number = glob.parseNumber(value);
return this.optional(element) || jQuery.isNumeric(number);
}
//Fix the range to use globalized methods
jQuery.extend(jQuery.validator.methods, {
range: function (value, element, param) {
var val = glob.formatNumber(value);
return this.optional(element) || (val >= param[0] && val <= param[1]);
}
});
});
</script>
<system.webServer>
(...)
<staticContent>
<mimeMap fileExtension=".json" mimeType="application/json" />
</staticContent>
</system.webServer>