Mar*_*ech 2 asp.net-mvc asp.net-mvc-4
我正在尝试编写一个在客户端工作的自定义验证器,验证所有复选框都已勾选.
这是模型上的声明:
[DeclarationsAccepted(ErrorMessage = "You must tick all declarations")]
public IList<DeclarationQuestion> DeclarationQuestions { get; set; }
Run Code Online (Sandbox Code Playgroud)
这是属性:
public class DeclarationsAccepted : ValidationAttribute, IClientValidatable
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var questions = value as IList<DeclarationQuestion>;
if (questions != null && questions.All(c => c.Answer))
{
return ValidationResult.Success;
}
return new ValidationResult("You must accepted all declarations to continue");
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var modelClientValidationRule = new ModelClientValidationRule
{
ValidationType = "declarationsaccepted",
ErrorMessage = FormatErrorMessage(metadata.DisplayName)
};
yield return modelClientValidationRule;
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止这么好,工作服务器端.
对于客户端,我按如下方式连接:
jQuery.validator.addMethod('declarationsaccepted', function (value, element, params) {
//Implement logic here to check all boxes are ticked
console.log(value);
return false;
}, '');
jQuery.validator.unobtrusive.adapters.add('declarationsaccepted', {}, function (options) {
options.rules['declarationsaccepted'] = true;
options.messages['declarationsaccepted'] = options.message;
});
Run Code Online (Sandbox Code Playgroud)
我正在显示如下的复选框:
@{ var questionIndex = 0; }
@foreach (var question in Model.DeclarationQuestions)
{
@Html.CheckBoxFor(model => Model.DeclarationQuestions[questionIndex].Answer, new { id = "DeclarationQuestions" + questionIndex})
questionIndex++;
}
Run Code Online (Sandbox Code Playgroud)
然后使用以下方法显示验证消息:
@Html.ValidationMessageFor(c => c.DeclarationQuestions)
Run Code Online (Sandbox Code Playgroud)
当我提交表单时,将显示该消息,但仅在回发到服务器之后.有没有办法让这个在客户端工作?
小智 5
您不会获得客户端验证的原因是因为html帮助程序data-val-*为与属性关联的控件生成属性.jquery.validate.unobtrusive在解析表单时使用规则读取这些属性,并在ValidationMessageFor()与该控件关联的相应元素中显示错误消息(通过匹配id元素的属性来实现此目的 - 错误消息在跨度中生成<span for="TheIdOfTheAssociatedControl" ...>).
你没有(并且不能)生成属性控件DeclarationQuestions(仅适用于每个项目的属性,DeclarationQuestions所以没有任何东西可以匹配.
您可以通过包含自己的错误消息占位符和拦截.submit事件来处理此问题
html(将css添加到样式#conditions-error中display:none;)
<span id="delarations-error" class="field-validation-error">
<span>You must accept all declarations to continue.</span>
</span>
Run Code Online (Sandbox Code Playgroud)
脚本
var declarationsError = $('#delarations-error');
$('form').submit(function() {
var isValid = $('.yourCheckBoxClass').not(':checked') == 0;
if(!isValid) {
declarationsError.show(); // display error message
return false; // prevent submit
}
});
$('.yourCheckBoxClass').change(function() {
if($(this).is(':checked')) {
declarationsError.hide(); // hide error message
}
});
Run Code Online (Sandbox Code Playgroud)
旁注:你应该循环生成复选框
for (int i = 0; i < Model.DeclarationQuestions.Count; i++)
{
@Html.CheckBoxFor(m => m.DeclarationQuestions[i].Answer, new { id = "DeclarationQuestions" + i})
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2402 次 |
| 最近记录: |