jQuery不显眼的验证来验证表单的一部分

chi*_*oro 0 jquery-validate unobtrusive-validation asp.net-mvc-3

我们有一个ASP.NET MVC 3应用程序,它使用不显眼的jQuery验证.该页面允许在同一个go中将子对象添加到模型中.在<form>包含孩子的网格,并增加新的孩子一些输入字段.

将问题作为模型和子任务作为子项的简化示例:

Issue.cshtml - >定义表单并包含问题的字段及其子任务.

@model Issue
@using (Html.BeginForm("Create", "Issues", FormMethod.Post, new { id = "mainForm" })
{
    @Html.TextBoxFor(model => model.Summary)
    @Html.Partial("SubtaskFields", new Subtask())
    @Html.Partial("SubtasksGrid", model.Subtasks)
}
Run Code Online (Sandbox Code Playgroud)

SubtaskFields.cshtml:

@model Subtask

@Html.TextBoxFor(model => model.Summary)

<button id="add">Add</button>
Run Code Online (Sandbox Code Playgroud)

SubtasksGrid.cshtml:

@model IEnumerable<Subtask>

<table>
    @foreach (var subtask in Model)
    {
        <tr>
            <td>
                @subtask.Name
                <input type="hidden" name="Subtasks[@subtask.Index].Name" value="@subtask.Name"/>
            </td>
        </tr>
    }
</table>
Run Code Online (Sandbox Code Playgroud)

关键是,在提交表单时,只应验证和提交问题的属性(例如,Issue.Name),以及子项的隐藏字段(例如Subtask.Name).

我们有一些挂钩"添加"按钮的javascript代码,并根据SubtaskFields.cshtml局部视图中的值添加一个新的子任务.该脚本首先验证输入字段.为了使它能够工作,我们也使用了TextBoxFor用于SubtaskFields.cshtml的等html助手,渲染了一个虚拟/默认的子任务对象(new Subtask()).我们的javascript用于$("#mainForm").validate().element(...)在添加新子任务之前验证SubtaskFields.

这种方法的一个大问题是jQuery不显眼的验证框架会自动挂钩提交按钮并在提交表单之前验证表单中的所有字段.即,即使是子任务字段也经过验证.这没有任何意义.假设子任务名称是必需的(这意味着用户只有在填写了子任务名称时才能单击"添加").但是,如果用户没有单击"添加",则子任务字段中的值没有任何意义,尤其可以留空.在这种情况下,在我们当前的设置中,jQuery验证失败,因为必填字段留空.

怎么解决这个问题?

chi*_*oro 5

这就是我们想出的:

  1. 添加到所有的子任务的字段属性(这应该不是提交表单时进行验证),例如"数据-VAL-忽略".
  2. ignore表单验证器上的设置设置为"[data-val-ignore]"
  3. 对于添加按钮,为了验证子任务字段(通常被忽略),迭代它们,并为每个字段删除属性,重新解析以生成规则,执行验证,添加属性,再解析一个时间.

广告2:

$(document).ready(function () {
    $.data($('form')[0], 'validator').settings.ignore = "[data-val-ignore]";
});
Run Code Online (Sandbox Code Playgroud)

广告3:

$(allSubtaskFields).each(function() {
    $(this).removeAttr("data-val-ignore");
    $.validator.unobtrusive.parseElement(this, false);
    if (!$("mainForm").validate().element($(this))) { result = false; }
    $(this).attr("data-val-ignore", "true");
    $.validator.unobtrusive.parseElement(this, false);
});
Run Code Online (Sandbox Code Playgroud)