我有一个迷你表单,包含所有选择框和复选框列表。
我已经在viewmodel中设置了数据注释。因此,如果我提交表单(没有启用javascript),ModelState.IsValid
的工作方式就像它应该的那样。
但在客户端验证中,我遇到了问题。我有不引人注意的jquery验证,但是当我做$("#form").valid()
时,它总是返回true。
我不确定如何自定义并检查条件。例如,我有一个复选框列表,默认情况下没有选中任何内容。因此,如果未选中任何内容,.valid()
应返回false。此外,其中2个下拉列表中有一个“请选择”选项,但jquery仍然返回有效。服务器端ModelState.IsValid
适用于这两种情况。
以下是一个例子:
@using (Html.BeginForm("index", "home", FormMethod.Post, new { @id = "miniForm" })) {
@Html.ValidationSummary(true)
@Html.AntiForgeryToken()
<div>
@Html.LabelFor(m => m.NinjaType)
@Html.DropDownListFor(m => m.NinjaType, Model.NinjaTypeList) // First value is '0'. Rest of the list is of type STRING
</div>
/// following is the rendered html code as i created a helper for it which i've omitted in this example
<ul>
<li><input type="checkbox" id="poo1" name="pie" value="one" />one</li>
<li><input type="checkbox" id="poo2" name="pie" value="two" />two</li>
<li><input type="checkbox" id="poo3" name="pie" value="three" />three</li>
</ul>
<input type="submit" id="submitButton" />
}
如果有帮助,这是POST控制器操作:
public ActionResult Index(SuperDooperNinjaViewModel m)
{
if (this.ModelState.IsValid)
return Redirect("win");
else
return Redirect("fail");
}
我在想{我在$('#submitButton').click();
做老式的方式,但我觉得可能有更好的方法来做到这一点。我想到的另一种方法是将其转换为Ajax形式。因此,在服务器端响应中,我返回Redirect("fail");
。
JsonResult
总而言之,验证此表单的最佳途径是什么?
提前致谢
更新
视图模型:
public class SuperDooperViewModel
{
[Required]
public string NinjaType {get;set;}
public IEnumerable<SelectItemList> { get;set; }
[Required]
public string[] pie {get;set;} // checkbox
public IEnumerable<string> PieList { get;set; } // list of values for checkbox
}
在jquery中,我正在测试它:
$("#submitButton").click(function(e) {
e.preventDefault();
if ($("#miniForm").valid())
alert("valid");
else
alert("fail");
});
答案 0 :(得分:1)
对于下拉列表,这很简单:
public class SuperDooperNinjaViewModel
{
[Required]
public string NinjaType { get; set; }
public SelectList NinjaTypeList { get; set; }
}
并在视图中:
@Html.DropDownListFor(
m => m.NinjaType,
Model.NinjaTypeList,
"Please Select"
)
现在,对于复选框,您谈到了生成它们的一些HTML帮助程序,但是我看不到这个帮助程序发出任何用于不显眼验证的HTML5 data-*
属性。
答案 1 :(得分:0)
我不确定这是否是最好的方法,但是现在,我已经抛出了checkboxlist扩展名,只是手动完成了这个:
@foreach(var nt in Model.NinjaTypeList)
{
<li>@Html.CheckBox("pie", new { @id = nt })</li>
}
@Html.HiddenFor(m => m.NinjaType)
在jquery中,我将一个事件附加到复选框:
$('input[name=pie]').click(function(){
var pie = "";
$('input[name=pie]').each(function(i) {
if ($(this).is(':checked'))
pie += $(this).val() + ';';
});
$("#NinjaType").val(pie);
});
在我的控制器中:
public ActionResult Index(SuperDooperViewModel m, string[] pie)
{
/// I've add the following as a work around:
if (string.IsNullOrEmpty(m.NinjaType) // no reason it should be, but it's a sort of failsafe
{
if(pie.Any())
m.NinjaType = string.Join(";", pie.Where(w => w != "false"));
}
// rest of the controller here
}
这基本上可以满足我的需要,但对我来说这似乎是一项工作。任何改进都将受到赞赏。