【问题标题】:How to set unobtrusive validation for UI elements rendered using jQuery如何为使用 jQuery 呈现的 UI 元素设置不显眼的验证
【发布时间】:2018-07-12 16:39:24
【问题描述】:

我有一个 Razor 视图,它使用 HTML 帮助程序和其他使用 jQuery DataTable 的下拉菜单,

<div class="form-group">
            @Html.LabelFor(model => model.CarTyres, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-2">
                @Html.ListBoxFor(model => model.SelectedCarTyres, Model.CarTyres, htmlAttributes: new { @class = "selectpicker form-control", @multiple = "", @data_actions_box = "true" })
                @Html.ValidationMessageFor(model => model.SelectedCarTyres, "", new { @class = "text-danger" })

            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.Drivers, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-2">
                @Html.ListBoxFor(model => model.SelectedDrivers, Model.Drivers, htmlAttributes: new { @class = "selectpicker form-control", @multiple = "", @data_actions_box = "true" })
                @Html.ValidationMessageFor(model => model.SelectedDrivers, "", new { @class = "text-danger" })
            </div>
        </div>
        <div class="form-group">
            @Html.LabelFor(model => model.CarJacks, htmlAttributes: new { @class = "control-label col-md-2" })

            <div class="col-md-5">
                <table id="filtersTable">
                    <thead>
                        <tr>
                            <th>Select</th>
                            <th>Name</th>
                        </tr>
                    </thead>
                </table>
            </div>
            @Html.ValidationMessageFor(model => model.CarJacksCheckBox, "", new { @class = "text-danger" })
        </div>

在我的模型中,我将 required 设置为 true,这样当我检查 Model.IsValid() 时,如果未设置任何这些项目,它将返回 false,并且效果很好。

  public class ReportViewModel
    {
        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }


        [Required]
        public ICollection<int> SelectedCarTyres { get; set; }
        public IEnumerable<SelectListItem> CarTyres { get; set; }

        [Required]
        public ICollection<int> SelectedDrivers { get; set; }
        public IEnumerable<SelectListItem> Drivers { get; set; }


        public IEnumerable<CarJackViewModel> CarJacks { get; set; }

        [Required]
        public string SelectedSampleTime { get; set; }
        public IEnumerable<SelectListItem> SampleTimes { get; set; }



        [Required]
        public IEnumerable<int> CarJacksCheckBox { get; set; }


    }

为了使 javascrip 数据表成为必需,我复制了复选框上的验证属性,如下所示:

 $('#filtersTable').DataTable(
        {
            "iDisplayLength": 25,
            "ajax": {
                "url": "/CarJacks/Loaddata",
                "type": "GET",
                "datatype": "json"
            },
            "columns": [
                {
                    "data": "IsSelected",
                    "render": function (data, type, row) {
                        if (type === 'display') {
                            return '<input type="checkbox" name="CarJacksCheckBox" class="editor-active" data-val="true"  data-val-required="The CarJacks field is required.">';
                        }
                        return data;
                    }

            ],
            "rowCallback": function (row, data) {
                //Removed for Brevity
            }
        }
    );

但是,当没有选择 CarJackCheckBox 时,我没有得到任何客户端验证。

虽然 (ModelState.IsValid) 返回 false,$(form).valid() 返回 true,因此客户端没有错误。

我错过了哪一部分?

【问题讨论】:

  • 你想要什么验证?您是否要求至少选择一个复选框?
  • @StephenMuecke,是的。正如我设置的那样,[必需] public IEnumerable CarJacksCheckBox { get;放; } ,至少需要选中一个复选框,否则 Model.IsVaid() 将始终失败..
  • jquery.validate.unobtrusive.js 不提供该功能。您需要编写自己的脚本
  • 好的,我看到了几个链接,他们正在检查所选项目的数组,然后验证长度,将遵循这一点。也请让我知道任何好的链接,你可能知道..
  • 我依稀记得在一两年前回答过一个类似的问题,但现在还找不到。如果我这样做了会 ping 你,或者稍后添加答案

标签: javascript jquery asp.net-mvc razor unobtrusive-validation


【解决方案1】:

您不能使用 MVC 的客户端验证,因为验证规则应用于表单控件,并且您没有(也不能)为您的 IEnumerable&lt;int&gt; CarJacksCheckBox 属性创建表单控件。您需要编写自己的脚本来验证是否需要至少一个复选框。

从复选框中删除 data-val-* 属性(因为它们毫无意义)并添加一个额外的类名,例如 carjacks 以在脚本中用作 jQuery 选择器。

然后包含以下脚本(注意这些模仿“惰性”验证 - 它首先在提交时验证,然后在单击复选框时验证)

var validateOnClick = false; // for lazy validation
var requiredCarJacks = 1;
var carJacks= $('.carjacks');
var errorMessage = 'Select at least 1 car jack';
var errorElement = $('span[data-valmsg-for="CarJacksCheckBox"]');

function validateCarJacks() {
    var selectedCarJacks = carJacks.filter(':checked').length;
    var isValid = selectedCarJacks > requiredCarJacks ;
    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 () {
    if (!validateCarJacks()) {
        validateOnClick = true; // signal that we should now validate the .click() event
        return false; // prevent submit
    }
});

carJacks.click(function() {
    if (validateOnClick) {
        validateCarJacks();
    }
})

【讨论】:

  • 我只需要进行一项更改。而不是 var selectedCarJacks = carJacks.filter(':checked').length;我必须做 var selectedCarJacks = $('.carjacks').filter(':checked').length ,否则它总是为零且无效。任何指示为什么 carJacks 在函数之外无法工作但 errorMessage 和 errorElement 工作正常。
  • 您的脚本是否位于文档的末尾 - 即紧接在结束 &lt;/body&gt;tag 之前? (否则您需要将其全部包装在 $(document).ready() 中)
  • 最好的猜测是你在 $('#filtersTable').DataTable( 脚​​本之前就有了,所以 class="carjacks" 的复选框尚未创建。
  • 我也怀疑这一点,并为创建命令做了一个控制台日志。首先初始化 carjacks 类,所有脚本都在文档中准备就绪..$(function(){--所有代码在这里 - -});
  • 我只能假设 DataTable 脚本正在异步生成输入,并且在调用 var carJacks= $('.carjacks'); 时它们实际上并未添加到 DOM 中
【解决方案2】:

你必须在jQuery DataTable初始化后添加一行。

$.validator.unobtrusive.parse('form')

另外,你可以使用 jQuery Selector

$.validator.unobtrusive.parse('#formTable')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多