【问题标题】:JQuery Validate multiple rows only when checkbox is checkedJQuery仅在选中复选框时验证多行
【发布时间】:2015-09-07 17:08:58
【问题描述】:

我有一个 razor mvc 5 视图,我想在其中验证一些值。

模型

public partial class PersonViewModel
{
   [Required]
   public string FirstName { get; set; }

   [Required]
   public string LastName { get; set; }
}

观点

@using (Html.BeginForm("Process", "SomeController", FormMethod.Post, new { id = "processForm", enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()

<!-- Buttons -->
<div class="row btn-row">
    <div class="col-md-12">
        <div class="pull-right">
            <button class="btn btn-success"><span class="glyphicon glyphicon-floppy-save"></span> Save</button>
        </div>
    </div>
</div>
<!-- some more html -->
    for (int i = 0; i < Model.Count; i++)
    {
        <tr>
            <td>
                @Html.CheckBoxFor(m => m[i].ToBeProcessed, new {@id = "[" + i + "[.ToBeProcessed"})
            </td>
            <td>
                @Html.TextBoxFor(m => m[i].FirstName, new {@id = "[" + i + "].FirstName"})
                @Html.ValidationMessageFor(m => m[i].FirstName, "Please enter a value", new {@class = "text-danger"})
            </td>
            <td>
                @Html.TextBoxFor(m => m[i].LastName, new {@id = "[" + i + "].LastName"})
                @Html.ValidationMessageFor(m => m[i].LastName, "Please enter a value", new {@class = "text-danger"})
            </td>
        </tr>
    }
    <!-- some more html -->
    } <!-- form close -->

我只想验证复选框 [i].ToBeProcessed 被选中的行。其他行中的文本框应被忽略。

在我的 jQuery 中,我有以下代码:

@section Scripts {
    @Script.Render("~/bundles/jqueryval")

    <script type="text/javascript">
        $(function(){
            $("#processForm").validate({
                rules: {"[0].FirstName": {required: "[0].ToBeProcessed:checked"},
                       {"[1].FirstName": {required: "[1].ToBeProcessed:checked"},
                       {"[0].LastName": {required: "[0].ToBeProcessed:checked"},
                       {"[1].LastName": {required: "[1].ToBeProcessed:checked"} // note that this is only fixed for testing purposes
                });
            });
        </script>
}

现在,在运行代码时,选中第一个复选框并点击提交按钮,所有文本字段都会被验证,而不仅仅是第一行中的那些。

【问题讨论】:

  • 你的模型看起来怎么样?
  • @Dandy 我已经添加了模型。
  • 检查Conditional Validation using DataAnnotation,特别是RequiredIfAttribute。它还具有客户端验证。
  • 使用 foolproof [RequiredIfTrue("ToBeProcessed")] 或类似的属性应用于您的 FirstNameLastName 属性 - 您可以获得客户端和服务器端验证
  • @StephenMuecke 万无一失是适合我的解决方案。我已经为面临相同问题的任何人提供了答案

标签: jquery asp.net-mvc validation


【解决方案1】:

您可以按如下方式添加验证,这不是最好的方法,但有效

 @for (int i = 0; i < Model.Count; i++)
            {
                <tr>
                    <td>
                        @Html.CheckBoxFor(m=>m[i].ToBeProcessed, new { @id = "ToBeProcessed_" + i })
                    </td>
                    <td>
                        @Html.TextBoxFor(m=>m[i].FirstName, new { @id ="FirstName_"+i})
                        @Html.ValidationMessageFor(m => m[i].FirstName)
                    </td>
                    <td>
                        @Html.TextBoxFor(m => m[i].LastName, new { @id = "LastName_"+i})
                        @Html.ValidationMessageFor(m => m[i].LastName)
                    </td>
                </tr>
            }

并将您的验证规则生成为

@section Scripts {
    @Script.Render("~/bundles/jqueryval")

    <script type="text/javascript">
        $(function(){
        $('#processForm').validate();

        @for(int i = 0; i < Model.Count; i++)
        {
        <text>
        $("#FirstName_@i").rules("add", {
            required: "#ToBeProcessed_@i:checked"
        });

        $("#LastName_@i").rules("add", {
            required: "#ToBeProcessed_@i:checked"
        });

        </text>
        }
    });
    </script>
}

要获得更多控制,您应该使用@Zabavsky 文章链接。

【讨论】:

  • 它不起作用 - 没有具有id 属性的控件,格式为#ToBeProcessed_@i
  • 它将被渲染为ToBeProcessed_0ToBeProcessed_1等。它的内部剃须刀for循环。
  • 不会。它将是 id="_0__ToBeProcessed" name="[0].ToBeProcessed" 更不用说它没有意义了,因为真正的验证发生在他的服务器上,这并没有解决这个问题(ModelState 仍然无效)
  • 这很奇怪。我得到它完全呈现为&lt;input checked="checked" data-val="true" data-val-required="The ToBeProcessed field is required." id="ToBeProcessed_0" name="[0].ToBeProcessed" type="checkbox" value="true"&gt;。我在@Html.CheckboxFor 中有 html 属性对象。并且服务器验证不关心元素 id。
  • 不,它关心属性的名称和值以及应用于它们的属性,因此这对解决服务器端验证没有任何作用,这是关键验证(客户端验证是一个不错的奖励,但可以轻松被绕过)。并且 OP 已经添加了一个答案,显示了执行此操作的正确方法
【解决方案2】:

使用万无一失解决了这个问题 因为我使用的是 MVC 5,所以不应该包含所有的 javascript 文件。使其工作的步骤:

第 1 步 通过 nugget 下载 Foolproof(安装包万无一失)

第 2 步在您的 BundleConfig.cs 添加:

bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*"));

bundles.Add(new ScriptBundle("~/bundles/mvcfoolproof").Include(                       
                    "~/Scripts/MvcFoolproofJQueryValidation.min.js",
                    "~/Scripts/mvcfoolproof.unobtrusive.min.js"));

第 3 步 将包添加到视图中(确保首先加载 JQuery。对我来说,我已经在我的 _Layout.cshtml 中加载了 JQuery 包)并在我的特定视图中添加了以下包:

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    @Scripts.Render("~/bundles/mvcfoolproof")
}

第 4 步 在我的模型中,我有

public partial class Person
{
    public bool ToBeProcessed {get; set;}

    [RequiredIfTrue("ToBeProcessed")]
    public string FirstName {get; set;}

    [RequiredIfTrue("ToBeProcessed")]
    public string LastName {get; set;}
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多