2015-03-13 54 views
2

我正在尝试编写一个客户端验证所有复选框都已勾选的自定义验证器。MVC客户端列表的自定义验证

这里的模型上的声明:

[DeclarationsAccepted(ErrorMessage = "You must tick all declarations")]   
    public IList<DeclarationQuestion> DeclarationQuestions { get; set; } 

而这里的属性:

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

到目前为止好,做工服务器端。

对于我布线这件事作为客户端如下:

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

我显示复选框这样的:

@{ var questionIndex = 0; } 
     @foreach (var question in Model.DeclarationQuestions) 
     { 

       @Html.CheckBoxFor(model => Model.DeclarationQuestions[questionIndex].Answer, new { id = "DeclarationQuestions" + questionIndex}) 

      questionIndex++; 
     } 

然后显示使用该验证消息:

@Html.ValidationMessageFor(c => c.DeclarationQuestions) 

当我提交表单时,消息会显示出来,但只有在回发到服务器后才会显示。有没有什么办法可以让客户端工作?

+1

任何验证工作的客户端?如果不是,你需要包含jquery.validate.js和jquery.validate.unobtrusive.js。 – KevDevMan 2015-03-13 15:55:20

+0

是验证在客户端工作,我可以将该属性应用于其他属性,例如一个文本输入。 – 2015-03-13 16:11:22

回答

4

您不会得到客户端验证的原因是因为html助手会为与属性相关的控件生成data-val-*属性。 jquery.validate.unobtrusive在表单解析并使用规则时读取这些属性,在由该控件关联的ValidationMessageFor()生成的相应元素中显示错误消息(它通过匹配元素的id属性来执行此操作 - 错误消息是在一个范围内生成的与<span for="TheIdOfTheAssociatedControl" ...>)。

你没有(和广东话)产生财产DeclarationQuestions(仅适用于DeclarationQuestions每个项目的性质的控制,没有什么可以匹配。

您可以通过包括您自己的错误处理这消息占位符和拦截.submit事件

HTML(以款式#conditions-error添加CSS为display:none;

<span id="delarations-error" class="field-validation-error"> 
    <span>You must accept all declarations to continue.</span> 
</span> 

脚本

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

旁注:您产生的复选框回路应

for (int i = 0; i < Model.DeclarationQuestions.Count; i++) 
{ 
    @Html.CheckBoxFor(m => m.DeclarationQuestions[i].Answer, new { id = "DeclarationQuestions" + i}) 
} 
+0

谢谢。我将使用上述建议的解决方案来实施 – 2015-03-16 08:33:34