2011-10-13 111 views
0

我们有一个使用不显眼的jQuery验证的ASP.NET MVC 3应用程序。该页面允许在同一行程中将儿童对象添加到模型中。 <form>包含儿童网格和一些用于添加新儿童的输入字段。jQuery不显眼的验证来验证表单的一部分

有问题,因为型号和子任务为孩子们简单的例子:

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

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局部视图中的值添加了一个新的子任务。该脚本首先验证输入字段。为了达到这个目的,我们使用TextBoxFor等html帮助程序为SubtaskFields.cshtml,渲染虚拟/默认子任务对象(new Subtask())。我们的javascript使用$("#mainForm").validate().element(...)在添加新的子任务之前验证SubtaskFields。

的大问题,这种做法是jQuery的不引人注目的验证框架自动挂钩提交按钮,提交表单之前验证形式内的所有领域。即,即使是子任务字段也是有效的。这没有任何意义。假定子任务名称是强制性的(这意味着如果用户填写了子任务名称,用户只能点击“添加”)。但是,如果用户没有而不是点击“添加”,则子任务字段中的值没有任何意义,并且可以特别留空。在这种情况下,在我们当前的设置中,jQuery验证失败,因为必填字段留空。

这怎么解决?

回答

5

这是我们想出来的:

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

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

看起来你正在对付MVC egine在这里。 我会使用编辑器模板和显示模板,EditorFor模板的东西,你想验证和发布,显示模板的东西,你不想发布和验证..如果你有一个TextBoxFor在显示模板确保其绑定属性有没有必需的属性,如果它的值类型使它可以为空。

+0

嗨, 。我希望这个验证可以通过所有数据注释从视图模型中自动推断出来。 – chiccodoro

1

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

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

+0

嗨counsellorben。如果我这样做了,如何确保在按下“全局”提交按钮时一次提交所有数据(包括网格)? – chiccodoro

+0

您可以附加到提交按钮上的点击事件,为每个表单使用jquery选择器,并提交每个表单。 – counsellorben

+0

O.k .;但这意味着控制器需要分成多个控制器,每个控制器一个。而且,如果任何提交失败,错误必须被合并等。jquery的救援。 – chiccodoro

0

为了验证形式的一部分,与一个#id包裹要验证到一个div的部分或控制或.class并执行以下操作:

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