在表中为dynamic文本框设置类validation

我有一个有一排dynamic文本框的表格。 示例如下:

在这里输入图像描述

我通过点击[+]添加新的目标,在表格中添加下面的行将出现:

在这里输入图像描述

我想添加validation类到表格内的所有文本框。 所以当用户点击保存button时,它会检查所有的文本框。

我尝试使用这个jQuery的这个:

$('#tbTargetDetails tr').each(function () { $(this).find('td input:text').each(function (i,a) { // get each of the textbox and add validation class to it }); }); 

我正在使用MVC 5,jquery-1.10.2.js,jquery-1.10.2.min.js,jquery.validate *&Site.css有类input.inputvalidation错误

在我的模型中:

  public class ClsTargetInfo { public string ItemNumber_Target { get; set; } [Required] public string TargetColor_U { get; set; } [Required] public string TargetColor_V { get; set; } [Required] public string D90Target_U { get; set; } [Required] public string D90Target_V { get; set; } [Required] public string D10Target_U { get; set; } [Required] public string D10Target_V { get; set; } [Required] public string Thickness { get; set; } [Required] public string FilmWidth { get; set; } [Required] public string TargetDate { get; set; } } 

我在另一个模型中调用上面的模型:

 public class abc { public IList<ClsTargetInfo> TargetInfo { get; set; } } 

下面是我添加新行时的代码:

  $("#btnAddTarget").on("click", function (event) { AddTargetItem(jQuery('#txtTargetColorU').val(), jQuery('#txtD90TargetU').val(), jQuery('#txtD10TargetU').val(), jQuery('#txtTargetColorV').val(), jQuery('#txtD90TargetV').val(), jQuery('#txtD10TargetV').val(), jQuery('#txtThickness').val(), jQuery('#txtFilmWidth').val(), jQuery('#TargetDate').val()); }); function AddTargetItem(TargetColor_U, D90Target_U, D10Target_U, TargetColor_V, D90Target_V, D10Target_V, Thickness, FilmWidth, TargetDate) { var rowCount = $('#tbTargetDetails tr').length; //minus 1 row for header rowCount = rowCount - 2; var rowCountBil = rowCount + 1; var row = '<tr style="background-color:#ffffff;" id="tr_' + rowCount + '">'; row += '<td style="font-weight:bold;padding-left:5px;padding-top:0px;padding-bottom:0px;padding-right:0px;vertical-align:middle">' + rowCountBil + '</td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__TargetColor_U" name="TargetInfo[' + rowCount + '].TargetColor_U" type="text" value="' + TargetColor_U + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__TargetColor_V" name="TargetInfo[' + rowCount + '].TargetColor_V" type="text" value="' + TargetColor_V + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__D90Target_U" name="TargetInfo[' + rowCount + '].D90Target_U" type="text" value="' + D90Target_U + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__D90Target_V" name="TargetInfo[' + rowCount + '].D90Target_V" style="text-align:center;" type="text" value="' + D90Target_V + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__D10Target_U" name="TargetInfo[' + rowCount + '].D10Target_U" style="text-align:center;" type="text" value="' + D10Target_U + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__D10Target_V" name="TargetInfo[' + rowCount + '].D10Target_V" style="text-align:center;" type="text" value="' + D10Target_V + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__Thickness" name="TargetInfo[' + rowCount + '].Thickness" style="text-align:center;" type="text" value="' + Thickness + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__FilmWidth" name="TargetInfo[' + rowCount + '].FilmWidth" style="text-align:center;" type="text" value="' + FilmWidth + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px"><input class="form-control" id="TargetInfo_' + rowCount + '__TargetDate" name="TargetInfo[' + rowCount + '].TargetDate" style="text-align:center;" type="text" value="' + TargetDate + '" /></td>'; row += '<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px;vertical-align:top;"><img id="imgRemoveTarget" alt="Item Lookup" src="/Contenthttp://img.dovov.comtrashcan.png" style="cursor:pointer;width:32px;height:29px;" class="deleteLink" /></td>'; row += '</tr>'; //Hide the previous delete button $('#tbTargetDetails tr:last .deleteLink').hide('fast'); $('#tbTargetDetails tr:last').after(row); } 

请帮忙解决我的问题。 真的很感谢你们的帮助。 谢谢。

您没有在文本框中包含必要的data-val属性,也没有包含用于显示validation消息的占位符元素, jquery.validate.unobtrusive.js使用jquery.validate.unobtrusive.js来执行客户端validation。 另外,当前的实现不允许用户通过包含索引器的隐藏input来删除可以解决的最后一行以外的任何内容,这允许将非连续索引器发布并绑定到您的集合。

首先将一个默认的ClsTargetInfo对象添加到TargetInfo属性中,并在视图中生成其html

 <table id="table"> // add an id attribute <thead>.....</thead> <tbody is="tablebody"> // add an id attribute for(int i = 0; i < Model.TargetInfo.Count; i++) { <tr> <td> @Html.TextBoxFor(m => m.TargetInfo[i].TargetColor_U, new { id="", @class="form-control" }) // remove the unnecessary id attribute @Html.ValidationMessageFor(m => m.TargetInfo[i].TargetColor_U) // Add the following hidden input to only one column in the row <input type="hidden" name="TargetInfo.Index" value=@i /> </td> <td> @Html.TextBoxFor(m => m.TargetInfo[i].TargetColor_V, new { id="", @class="form-control" }) // remove the unnecessary id attribute @Html.ValidationMessageFor(m => m.TargetInfo[i].TargetColor_V) </td> .... // other columns </tr> } </tbody> </table> 

然后检查为<tr>元素生成的html,它应该看起来像这样

 <tr> <td> <input data-val="true" data-val-required="The TargetColor_U field is required" name="TargetInfo[0].TargetColor_U" type="text" value=""> <span class="field-validation-valid errorText" data-valmsg-for="TargetInfo[i].TargetColor_U" data-valmsg-replace="true"></span> <input type="hidden" name="TargetInfo.Index" value="0" /> </td> .... </tr> 

并将其复制到一个隐藏的元素中,该元素放置表单标记之外 ,并将所有索引器实例replace为一个虚拟字符,以使name="TargetInfo[0].TargetColor_U"变为name="TargetInfo[#].TargetColor_U" ),也replace隐藏的input的value属性,所以value="0"它变成value="#"

 <table id="newrow" style="display:none"> .... // copy the tr element and its contents here </table> 

那么脚本看起来就像

 var form = $('form'); // or use the id if you have given the form an id var newrow= $('#newrow'); var tablebody = $('#tablebody'); // modify to suit your id $("#btnAddTarget").click(function() { var index = (new Date()).getTime(); // unique indexer var clone = newrow.clone(); // clone the new row clone.html($(clone).html().replace(/#/g, index)); // update the indexer of the clone var row = clone.find('tr'); tablebody.append(row); // add the new row to the table // Reparse the validator form.data('validator', null); $.validator.unobtrusive.parse(form); }); 

边注:

  1. 不显眼的validation通过parsing表单首次呈现时的data-val属性起作用。 添加dynamic内容时,必须按照脚本的最后两行所示重新parsingvalidation器。
  2. 添加索引器的隐藏input允许您删除集合中的任何行,因此删除“删除”button不再是必要的,并且会给用户更好的体验。
  3. 而不是使用内联样式,而是使用css代替,而不是使用<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px">#table td { padding: 0; } #table td { padding: 0; }.css文件中
  4. 纯粹的客户端添加行的性能最好,但难以维护。 如果您在属性上添加或更改任何validation属性(例如,稍后可能会添加[StringLength]属性),则需要更新html以适应。 作为替代,您可以考虑使用BeginCollectionItem帮助程序,这意味着您有一个局部视图(表示一个表行)。 对于现有的项目,您使用@Html.Partial()foreach循环,对于新的行,使用ajax来调用返回部分视图的控制器方法,并更新DOM
 <script src="Scripts/jquery-1.10.2.min.js"></script> <script type="text/javascript"> $(document).ready(function () { function DeleteRow(btn) { //alert("delete" + btn); var tr = btn.closest('tr'); tr.remove(); } $(".btnsd").click(function () { // debugger; alert("hjkghk"); divs = $('.val') for (ind in divs) { var div = divs[ind]; if (div.value == "") { div.focus(); return false; } } $('#Employertbl').append( '<tr>' + '<td> @Html.TextBox("item.employer_name", null, new { @class = "form-control val" })</td>' + '<td width="24%"> <div style="float:left; padding-right:5px;">@Html.TextBox("item.duration_From", null, new { @id = "", @placeholder = "From Date", @class = "form-control input-date datepicker val", @readonly = true })</div> ' + '<div>@Html.TextBox("item.duration_to", null, new { @id = "", @class = "form-control input-date datepicker val", @placeholder = "To Date", @readonly = true })</div></td>' + '<td> @Html.TextBox("item.designation", null, new { @class = "form-control val" })</td>' + '<td> @Html.TextBox("item.worked_skill", null, new { @class = "form-control val" })</td>' + '<td> @Html.TextBox("item.proj_handled", null, new { @class = "form-control val" })</td>' + '<td> @Html.CheckBox("item.current_employed",new{@class = "current" })</td>' + '<td><input type="button" value="Remove" onclick="DeleteRow(this)" name="delete" class="btn blue pull-right" /> </td>' + '</tr>' ); }); }); </script> <div class="table-responsive"> <table id="Employertbl" class="table table-striped table-bordered table-hover dataTable no-footer"> <tbody> <tr> <th>Employer Name</th> <th>Duration</th> <th>Designation</th> <th>Worked skill(s)</th> <th>Reason of change</th> <th>Currently Employed</th> <th>Action</th> </tr> <tr> <td> <input class="form-control val" id="item_employer_name" name="item.employer_name" type="text" value=""> </td> <td width="24%"> <div style="float:left; padding-right:5px;"><input class="form-control input-date datepicker val hasDatepicker" name="item.duration_From" placeholder="From Date" type="text" value="" id="dp1459328857835"></div> <div> <input class="form-control input-date datepicker val hasDatepicker" name="item.duration_to" placeholder="To Date" type="text" value="" id="dp1459328857836"></div> </td> <td> <input class="form-control val" id="item_designation" name="item.designation" type="text" value=""> </td> <td> <input class="form-control val" id="item_worked_skill" name="item.worked_skill" type="text" value=""> </td> <td> <input class="form-control val" id="item_proj_handled" name="item.proj_handled" type="text" value=""> </td> <td> <input class="current" id="item_current_employed" name="item.current_employed" type="checkbox" value="true"><input name="item.current_employed" type="hidden" value="false"> </td> <td> <input id="myButton" type="button" value="add" name="delete" class="btnsd bcbn"> </td> </tr> <tr><td> <input class="form-control val" id="item_employer_name" name="item.employer_name" type="text" value=""></td><td width="24%"> <div style="float:left; padding-right:5px;"><input class="form-control input-date datepicker val hasDatepicker" name="item.duration_From" placeholder="From Date" type="text" value="" id="dp1459328857837"></div> <div><input class="form-control input-date datepicker val hasDatepicker" name="item.duration_to" placeholder="To Date" type="text" value="" id="dp1459328857838"></div></td><td> <input class="form-control val" id="item_designation" name="item.designation" type="text" value=""></td><td> <input class="form-control val" id="item_worked_skill" name="item.worked_skill" type="text" value=""></td><td> <input class="form-control val" id="item_proj_handled" name="item.proj_handled" type="text" value=""></td><td> <input class="current" id="item_current_employed" name="item.current_employed" type="checkbox" value="true"><input name="item.current_employed" type="hidden" value="false"></td><td><input type="button" id="myButton" value="add" name="delete" class="btnsd dfsd"> </td></tr> <tr><td> <input class="form-control val" id="item_employer_name" name="item.employer_name" type="text" value=""></td><td width="24%"> <div style="float:left; padding-right:5px;"><input class="form-control input-date datepicker val hasDatepicker" name="item.duration_From" placeholder="From Date" type="text" value="" id="dp1459328857839"></div> <div><input class="form-control input-date datepicker val hasDatepicker" name="item.duration_to" placeholder="To Date" type="text" value="" id="dp1459328857840"></div></td><td> <input class="form-control val" id="item_designation" name="item.designation" type="text" value=""></td><td> <input class="form-control val" id="item_worked_skill" name="item.worked_skill" type="text" value=""></td><td> <input class="form-control val" id="item_proj_handled" name="item.proj_handled" type="text" value=""></td><td> <input class="current" id="item_current_employed" name="item.current_employed" type="checkbox" value="true"><input name="item.current_employed" type="hidden" value="false"></td><td><input type="button" id="myButton" value="add" name="delete" class="btnsd"> </td></tr> </tbody> </table> </div>