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

时间:2011-10-13 09:24:04

标签: asp.net-mvc-3 jquery-validate unobtrusive-validation

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

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

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

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

SubtaskFields.cshtml:

@model Subtask

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

<button id="add">Add</button>

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>

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

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

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

如何解决这个问题?

4 个答案:

答案 0 :(得分:5)

这就是我们提出的:

  1. 向所有子任务字段添加属性(在提交表单时 ) “数据-VAL-忽略”。
  2. 将表单验证程序的ignore设置为"[data-val-ignore]"
  3. 对于添加按钮,为了验证子任务字段(通常被忽略),迭代它们,并为每个字段删除属性,重新解析以生成规则,执行验证,添加属性,再解析一次。
  4. 广告2:

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

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

答案 1 :(得分:1)

我建议将@Html.Partial("SubtasksGrid", model.Subtasks)移到表单之外,并将其放在一个单独的表单中,或者让部分为每个网格行生成一个表单。

这将解决您的主表单的验证问题,还应该允许您简化SubTasksGrid中每行的验证。

答案 2 :(得分:0)

看起来你在这里反对MVC egine。 我会使用编辑器模板和显示模板,编辑器模板用于您想验证和发布的内容,以及显示您不想发布和验证的内容的模板。如果您在显示模板中有TextBoxFor,请确保其绑定属性没有必需属性,如果它的值类型使其可以为空。

答案 3 :(得分:0)

要验证表单的一部分,请将要验证的部分或控件包装到包含#id.class的div中,然后执行以下操作:

var validator = $("#myForm").validate();
var isValid = true;
$("myDivToBeValidated").find("*[data-val]").each(function (indx, elem) {
if (!validator.element(elem)) {
    isValid = false;
}
});

//this part of form is valid however there might be some other invalid parts 
if (isValid) 
   //do your action, like go to next step in a wizard or any other action
   goToNextStep();

我希望很清楚,如果不是,请发表评论。有关jQuery validation pluginelement()函数的更多信息,check this