如何通过ASP.NET MVC中的自定义jQuery验证复选框列表 [英] How to validate a list of checkbox through custom jQuery in asp.net mvc
问题描述
我有一个复选框列表,我想在客户端使用jQuery进行验证,但失败了.我已经在项目中添加了简洁的jQuery验证插件.
I have a list of checkboxes that i want to validate on client side with jQuery but failing. I have already added unobtrusive and jquery validation plugin to my project.
型号代码为:
[Required]
public string name { get; set; }
[SkillValidation(ErrorMessage = "Select at least 3 skills")]
public List<CheckBox> skills { get; set; }
和其他模型是:
public class CheckBox
{
//Value of checkbox
public int Value { get; set; }
//description of checkbox
public string Text { get; set; }
//whether the checkbox is selected or not
public bool IsChecked { get; set; }
}
说明-SkillValidation()是我创建的用于服务器端验证的自定义属性.
Explanation - SkillValidation() is the custom attribute which i have created to do server side validation.
SkillValidation类代码为:
The SkillValidation class code is:
public class SkillValidation : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
List<CheckBox> instance = value as List<CheckBox>;
int count = instance == null ? 0 : (from p in instance
where p.IsChecked == true
select p).Count();
if (count >= 3)
return ValidationResult.Success;
else
return new ValidationResult(ErrorMessage);
}
}
说明:此代码将验证用户是否至少检查服务器端的3个复选框.我没有从 IClientValidatable 接口继承此类,因为我知道将无法通过MVC方式(不干扰方式)进行验证.
Explanation: This code will validate user to check at least 3 checkboxes on the server side. I did not inherited this class from IClientValidatable interface because i know it wont be possible to do validation from the MVC way (unobtrusive manner).
我的查看代码是:
@model demo.MVC.Models.CB
@{
HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
}
@using (Html.BeginForm())
{
<table>
<tr>
<td>
@Html.LabelFor(model => model.name)
@Html.EditorFor(model => model.name)
@Html.ValidationMessageFor(model => model.name)
</td>
<td>
@Html.LabelFor(model => model.skills)
@Html.CheckBoxFor(m => m.skills[0].IsChecked, new { id = "csharpSkill" }) C#
@Html.CheckBoxFor(m => m.skills[1].IsChecked, new { id = "aspSkill" }) ASP.NET
@Html.CheckBoxFor(m => m.skills[2].IsChecked, new { id = "jquerySkill" }) jQuery
@Html.CheckBoxFor(m => m.skills[3].IsChecked, new { id = "mvcSkill" }) ASP.NET MVC
@Html.CheckBoxFor(m => m.skills[4].IsChecked, new { id = "razorSkill" }) Razor
@Html.CheckBoxFor(m => m.skills[5].IsChecked, new { id = "htmlSkill" }) HTML
@Html.ValidationMessageFor(model => model.skills)
</td>
</tr>
<tr><td colspan="2"><button id="submitButton" type="submit">Submit</button></td></tr>
</table>
}
@Scripts.Render("~/jQuery")
@Scripts.Render("~/jQueryValidate")
@Scripts.Render("~/Unobtrusive")
说明:在视图中,我创建了名称文本框和6个使用 @ Html.CheckBoxFor()创建的技能的复选框.
Explanation: In the view i have created the text box for name and 6 checkboxes for the skills created with @Html.CheckBoxFor().
问题:问题是,如果我删除了6个复选框,则客户端验证对于名称文本框效果很好.
Problem: The problem is that If i remove the 6 checkboxes then client side validation works well for the name text box.
如果我放置6个复选框并按下按钮,则只有服务器端验证适用于名称和复选框.
If i put 6 checkboxes and press the button then only the server side validation works for name and checkboxe.
我希望客户端验证也适用于6个复选框,以便用户必须至少选择3个复选框.
I want client side validation to work for the 6 checkboxes too so that user has to select 3 checkboxes at least.
我该如何实现?
谢谢
推荐答案
使用MVC的客户端验证(通过实现IClientValidatable
和使用jquery.validation.unobtrusive.js)
)不能实现此目的.原因是客户端验证规则适用于表单控件,并且您不会(也不能)为您的skills
属性创建表单控件,该属性是一个集合,而不是简单的值类型.
You cannot achieve that using MVC's client side validation (by implementing IClientValidatable
and using jquery.validation.unobtrusive.js)
. The reason is that client side validation rules are applied to form controls, and you do not (and cannot) create a form control for your skills
property which is a collection, not a simple value type.
您需要编写自己的脚本来验证已选中复选框的数量(如果无效,请使用@Html.ValidationMessageFor(model => model.skills)
You need to write your own scripts to validate the number of checked checkboxes (and if not valid, make use of the placeholder generated by @Html.ValidationMessageFor(model => model.skills)
要模仿jquery的惰性"验证,请先处理.submit()
事件,然后再处理复选框的.click()
事件.
To mimic jquery's 'lazy' validation, initially handle the .submit()
event, and there after, handle the .click()
event of the checkboxes.
修改第二个<td>
元素,添加一个id
属性以选择复选框(另请参见下面的注释)
Modify your 2nd <td>
element to add an id
attribute for selecting the checkboxes (see also notes below)
<td id="skills">
.... // your checkboxes
并添加以下脚本
var validateSkillsOnCheck = false; // for lazy validation
var requiredSkills = 3;
var skills = $('#skills input[type="checkbox"]');
var errorMessage = 'Select at least 3 skills';
var errorElement = $('span[data-valmsg-for="skills"]');
// function to validate the required number of skills
function validateSkills() {
var selectedSkills = skills.filter(':checked').length;
var isValid = selectedSkills > requiredSkills;
if (!isValid) {
errorElement.addClass('field-validation-error').removeClass('field-validation-valid').text(errorMessage);
} else {
errorElement.addClass('field-validation-valid').removeClass('field-validation-error').text('');
}
return (isValid);
}
$('form').submit(function () {
validateSkillsOnCheck = true;
if (!validateSkills()) {
return false; // prevent submit
}
});
$('#skills').on('click', 'input', function () {
if (validateSkillsOnCheck) {
validateSkills();
}
})
一些注意事项.
- 表用于表格数据,而不用于布局和使用
<table>
元素不适合您的情况. - 您的
@Html.LabelFor(model => model.skills)
不适合(您 没有skills
的窗体控件,因此单击它不会 将重点放在任何事物上).那应该只是一个<span>@Html.DisplayNameFor(m =>m.skills)</span>
或类似的元素. -
但是,您应该为每个复选框创建标签.您的模型具有3个属性,包括
Text
和Value
,并且不清楚它们之间有什么区别,无论如何,您永远都不会在视图中包括它们.我认为您至少要提交Value
属性,以便您知道选择了哪些技能
- Tables are for tabular data, not layout and using a
<table>
element is not appropriate in your case. - Your
@Html.LabelFor(model => model.skills)
is not appropriate (you do not have a form control forskills
so clicking on it does not set focus to anything). That should just be a<span>@Html.DisplayNameFor(m =>m.skills)</span>
or similar element. You should however be creating labels for each checkbox. Your model has 3 properties including
Text
andValue
and its not clear what the difference is between them, and in any case, you never include them in the view. I assume your will want to submit at least theValue
property so you know which skills have been selected
<label>
@Html.CheckBoxFor(m =>m.skills[i].IsChecked)
<span>@Model.skills[i].Text</span>
</label>
@Html.HiddenFor(m =>m.skills[i].Value)
这篇关于如何通过ASP.NET MVC中的自定义jQuery验证复选框列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!