繁体   English   中英

如何通过asp.net mvc中的自定义jQuery验证复选框列表

[英]How to validate a list of checkbox through custom jQuery in asp.net mvc

我有一个复选框列表,我希望在客户端使用jQuery验证但失败。 我已经为我的项目添加了不显眼的jquery验证插件。

型号代码是:

 [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()是我创建的用于执行服务器端验证的自定义属性。

SkillValidation类代码是:

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方式进行验证(不引人注目的方式)。

我的查看代码是:

@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()创建的技能的复选框。

问题:问题是,如果我删除6个复选框,则客户端验证适用于名称文本框。

如果我放了6个复选框并按下按钮,那么只有服务器端验证适用于名称和复选框

我希望客户端验证也适用于6个复选框,以便用户至少选择3个复选框。

我怎样才能实现它?

谢谢

使用MVC的客户端验证(通过实现IClientValidatable和使用jquery.validation.unobtrusive.js)无法实现这jquery.validation.unobtrusive.js) 原因是客户端验证规则应用于表单控件,并且您不能(也不能)为您的skills属性创建表单控件,该表单控件是集合,而不是简单的值类型。

您需要编写自己的脚本来验证已选中复选框的数量(如果无效,则使用@Html.ValidationMessageFor(model => model.skills)生成的占位符@Html.ValidationMessageFor(model => model.skills)

为了模仿jQuery的“懒惰”的验证,初步处理.submit()之后的事件,在那里,处理.click()的复选框的事件。

修改你的第二个<td>元素以添加一个id属性来选择复选框(另见下面的注释)

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

一些旁注。

  1. 表格用于表格数据,而不是布局,在您的情况下使用<table>元素是不合适的。
  2. 您的@Html.LabelFor(model => model.skills)不合适(您没有skills的表单控件,因此单击它不会将焦点设置为任何内容)。 那应该是<span>@Html.DisplayNameFor(m =>m.skills)</span>或类似的元素。
  3. 但是,您应该为每个复选框创建标签。 您的模型有3个属性,包括TextValue并且不清楚它们之间的区别,并且在任何情况下,您都不会将它们包含在视图中。 我假设你想要提交至少Value属性,这样你就知道选择了哪些技能

     <label> @Html.CheckBoxFor(m =>m.skills[i].IsChecked) <span>@Model.skills[i].Text</span> </label> @Html.HiddenFor(m =>m.skills[i].Value) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM