我的ViewModel
Public Class ViewModel
<SelectOne()>
Public Property Collection As List(Of Item)
End Class
我的模特
Public Class Item
<SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
Public Property Selected As Boolean
Public Property Value As String
End Class
在我看来,我正在使用编辑模板
渲染ViewModel.Collection
@Html.CheckBoxFor(Function(item) item.Selected)
@Html.HiddenFor(Function(item) item.Value)
现在,我想要的是确保使用客户端验证至少检查一个复选框。
我可以通过在Item.Selected
属性上设置自定义验证属性并通过$.validator.unobtrusive.adapters.add()
但我觉得属性应该放在ViewModel.Collection
属性上,就像在服务器端一样,我已经在使用这个自定义验证验证集合的一个项目是否有Selected = True
:
<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SelectOneAttribute
Inherits ValidationAttribute
Protected Overrides Function IsValid(value As Object, validationContext As ValidationContext) As ValidationResult
Dim list As IList
If value Is Nothing Then
Return Nothing
End If
If TypeOf value Is IEnumerable Then
list = CType(value, IList)
Else
list = New Object() {value}
End If
Dim count As Integer = (From item In list
From prop In item.GetType().GetProperties()
Let attributes = prop.GetCustomAttributes(GetType(RequireOneOrMoreIndicatorAttribute), False)
Where attributes.Count > 0
From attribute In attributes
Where attribute.TargetValue = prop.GetValue(item, Nothing)).Count()
If count > 0 Then
Return Nothing
End If
Return New ValidationResult(FormatErrorMessage(validationContext.DisplayName))
End Function
End Class
它使用SelectOnePropertyAttribute
上的反射来查找要检查的属性:
<AttributeUsage(AttributeTargets.Field Or AttributeTargets.Property, AllowMultiple:=False, Inherited:=False)>
Public Class SelectOnePropertyAttribute
Inherits ValidationAttribute
Implements IClientValidatable
Public Property TargetValue As Object
Public Sub New(targetValue As Object)
Me.TargetValue = targetValue
End Sub
Public Overrides Function IsValid(value As Object) As Boolean
Return True
End Function
Public Function GetClientValidationRules(metadata As System.Web.Mvc.ModelMetadata, context As System.Web.Mvc.ControllerContext) _
As System.Collections.Generic.IEnumerable(Of System.Web.Mvc.ModelClientValidationRule) _
Implements System.Web.Mvc.IClientValidatable.GetClientValidationRules
Dim rule As New ModelClientValidationRule With {
.ValidationType = "selectone",
.ErrorMessage = Me.ErrorMessage
}
Return New ModelClientValidationRule() {rule}
End Function
End Class
这就是客户端验证
$.validator.unobtrusive.adapters.add("selectone", function (options) {
options.rules["selectone"] = {};
options.messages["selectone"] = options.message;
});
$.validator.addMethod("selectone", function (value, element, parameters) {
var $el = $(element),
name = $el.attr("name"),
field = name.replace(/\[.*$/, "").replace(".", "_"),
attr = name.replace(/^.*\./, ""),
test = new RegExp(field + "\\[\\d\\]\." + attr);
var inputs = $("input[id^=" + field + "]:not([disabled]):not([type=hidden])").filter("input[name$=" + attr + "]");
for(var i = 0; i < this.errorList.length; i++) {
var name = $(this.errorList[i].element).attr("name");
// Do not write out the error more than once.
if (test.test(name)) return true;
}
return inputs.length == 0 || inputs.filter(":checked:not([disabled])").val();
});
答案 0 :(得分:0)
您正在创建将在侧面运行的自定义验证,但如果您希望在客户端运行,则必须为该自定义验证创建JQuery,然后将其创建到您的页面。
请参阅以下链接
http://www.codeproject.com/Articles/275056/Custom-Client-Side-Validation-in-ASP-NET-MVC3
答案 1 :(得分:0)
进行以下更改: -
1.您的ViewModel: -
Public Class ViewModel
<SelectOne()>
<SelectOneProperty(TargetValue:=True, ErrorMessage:="Select at least one.")>
Public Property Collection As List(Of Item)
End Class
我的模特: -
公共类项目 公共属性选为布尔值 公共属性值为字符串 结束班
在您的视图中添加以下行:
@ Html.HiddenFor(X =&GT; x.ItemCollection)
4.然后您将运行视图并查看视图源,然后它将
4.然后您将提交代码,然后它将运行客户端验证。添加调试器并调试它
5.然后修改您的客户端脚本。 1.现在您可以从每个复选框中获取值并检查是否已选中任何复选框,然后提交表单,否则显示结果。
6.也可根据您的要求在SelectOnePropertyAttribute中进行更改
7.对于服务器端我在c#上完成了这段代码: -
[AttributeUsage((AttributeTargets.Field | AttributeTargets.Property),AllowMultiple = false,Inherited = false)] 公共类SelectOneAttribute:ValidationAttribute { public String PropertyName {get;组; }
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
bool boolVal = false;
IList list;
if (value == null)
{
return null;
}
if (value.GetType().Name == typeof(List<>).Name || value.GetType().Name == typeof(IList<>).Name)
{
list = (IList)value;
}
else
{
list = new object[] {value};
}
if (list.Count<0)
return null;
if ((from object item in list let propertyInfo = item.GetType().GetProperties() from info in propertyInfo where String.Equals(info.Name, PropertyName) && (bool)info.GetValue(item) == true select item).Any())
{
return null;
}
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
答案 2 :(得分:0)
这是你需要的吗?如果没有选中“myCheckbox”,它将阻止表单提交......
$(document).ready(function () {
$('#submitButtonId').click(function (e) {
if ($('input[name=myCheckbox]:checked').length == 0) {
e.preventDefault();
alert('Please choose at least one checkbox before continuing!');
}
});
});