如何为使用 jQuery 呈现的 UI 元素设置不显眼的验证
Posted
技术标签:
【中文标题】如何为使用 jQuery 呈现的 UI 元素设置不显眼的验证【英文标题】:How to set unobtrusive validation for UI elements rendered using jQuery 【发布时间】: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您不能使用 MVC 的客户端验证,因为验证规则应用于表单控件,并且您没有(也不能)为您的 IEnumerable<int> 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 工作正常。 您的脚本是否位于文档的末尾 - 即紧接在结束</body>
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')
【讨论】:
以上是关于如何为使用 jQuery 呈现的 UI 元素设置不显眼的验证的主要内容,如果未能解决你的问题,请参考以下文章
如何为 JQuery addClass/removeClass 函数设置动画?
如何为单个 HTML 元素重新加载或重新渲染 CSS? [复制]
如何为 Kendo UI jQuery 的电子表格重新加载数据?