在表中设置动态文本框的类验证 [英] Set class validation for dynamic textbox in a table
问题描述
我有一个表有一行动态文本框。示例如下:
p>
我通过点击[+]添加新目标在表格中添加一行。屏幕下方会显示:
我要添加验证类到表中的所有文本框。所以当用户点击保存按钮,它会检查所有的文本框。
我尝试使用这个jquery:
$('#tbTargetDetails tr')。each(function(){
$(this).find('td input:text')。 (function(i,a){
//获取每个文本框并向其添加验证类
});
});
我使用MVC 5,jquery-1.10.2.js,jquery-1.10.2。 min.js,jquery.validate *&具有类 input.input-validation-error
的Site.css在我的模型中:
public class ClsTargetInfo
{
public string ItemNumber_Target {get;组; }
[必需]
public string TargetColor_U {get;组; }
[必需]
public string TargetColor_V {get;组; }
[必需]
public string D90Target_U {get;组; }
[必需]
public string D90Target_V {get;组; }
[必需]
public string D10Target_U {get;组; }
[必需]
public string D10Target_V {get;组; }
[必需]
public string Thickness {get;组; }
[必需]
public string FilmWidth {get;组; }
[必需]
public string TargetDate {get;组; }
}
我在另一个模型中调用上面的模型:
public class abc
{
public IList< ClsTargetInfo> TargetInfo {get;组; }
}
下面是添加新行时的代码:
$(#btnAddTarget)。on(click,function(event){
AddTargetItem(jQuery('#txtTargetColorU ').val(),jQuery('#txtD90TargetU')。val(),jQuery('#txtD10TargetU')。val(),
jQuery('#txtTargetColorV')。val #txtD90TargetV')。val(),jQuery('#txtD10TargetV')。val(),
jQuery('#txtThickness')。 ('#TargetDate')。val());
});
function AddTargetItem(TargetColor_U,D90Target_U,D10Target_U,TargetColor_V,D90Target_V,D10Target_V,Thickness,FilmWidth,TargetDate){
var rowCount = $('#tbTargetDetails tr')。
//为标题减去1行
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_Uname =TargetInfo ['+ rowCount +'] .TargetColor_Utype =textvalue ='+ 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_Vname =TargetInfo ['+ rowCount +'] .TargetColor_Vtype =textvalue ='+ 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_Uname =TargetInfo ['+ rowCount +'] .D90Target_Utype =textvalue ='+ 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_Vname =TargetInfo ['+ rowCount +'] .D90Target_Vstyle =text-align:center; type =textvalue ='+ 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_Uname =TargetInfo ['+ rowCount +'] .D10Target_Ustyle =text-align:center; type =textvalue ='+ 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_Vname =TargetInfo ['+ rowCount +'] .D10Target_Vstyle =text-align:center; type =textvalue ='+ 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 +'__Thicknessname =TargetInfo ['+ rowCount +'] .Thicknessstyle =text-align:center; type =textvalue ='+ Thickness +'/>< / td>';
row + ='< td style =padding-left:0px; padding-top:0px; padding-bottom:0px; padding-right:0px>< input class =form-control id =TargetInfo_'+ rowCount +'__FilmWidthname =TargetInfo ['+ rowCount +'] .FilmWidthstyle =text-align:center; type =textvalue ='+ FilmWidth +'/>< / td>';
row + ='< td style =padding-left:0px; padding-top:0px; padding-bottom:0px; padding-right:0px>< input class =form-control id =TargetInfo_'+ rowCount +'__TargetDatename =TargetInfo ['+ rowCount +'] .TargetDatestyle =text-align:center; type =textvalue ='+ TargetDate +'/>< / td>';
row + ='< td style =padding-left:0px; padding-top:0px; padding-bottom:0px; padding-right:0px; vertical-align:top;>< img id =imgRemoveTargetalt =Item Lookupsrc =/ Content / images / trashcan.pngstyle =cursor:pointer; width:32px; height:29px; class =deleteLink/>< / td>';
row + ='< / tr>';
//隐藏上一个删除按钮
$('#tbTargetDetails tr:last .deleteLink')hide('fast');
$('#tbTargetDetails tr:last')。after(row);
}
请帮助解决我的问题。真的很感谢你们的帮助。
谢谢。
您未包含必要的 data-val
属性到文本框,或者显示验证消息的占位符元素,它们由 jquery.validate.unobtrusive.js
用于执行客户端验证。此外,您当前的实现不允许用户删除任何其他可以解决的最后一行,包括索引器的隐藏输入,允许不连续的索引器发布并绑定到您的集合。
首先,在 TargetInfo
属性中添加一个默认 ClsTargetInfo
其在视图中的html
< table id =table> // add a id attribute
< thead> .....< / thead>
< tbody is =tablebody> //添加id属性
for(int i = 0; i {
< tr>
< td>
@ Html.TextBoxFor(m => m.TargetInfo [i] .TargetColor_U,new {id =,@ class =form-control})//删除不必要的id属性
@ html.ValidationMessageFor(m => m.TargetInfo [i] .TargetColor_U)
//将以下隐藏输入添加到行中的一列
< input type =hiddenname = TargetInfo.Indexvalue = @ i />
< / td>
< td>
@ Html.TextBoxFor(m => m.TargetInfo [i] .TargetColor_V,new {id =,@ class =form-control})//删除不必要的id属性
@ Html.ValidationMessageFor(m => m.TargetInfo [i] .TargetColor_V)
< / td>
.... //其他列
< / tr>
}
< / tbody>
< / table>
然后检查它为< tr>
元素应该看起来像
< tr&
< td>
< input data-val =truedata-val-required =TargetColor_U字段是必需的name =TargetInfo [0] .TargetColor_Utype =textvalue =
< span class =field-validation-valid errorTextdata-valmsg-for =TargetInfo [i] .TargetColor_Udata-valmsg-replace =true>< / span>
< input type =hiddenname =TargetInfo.Indexvalue =0/>
< / td>
....
< / tr>
并将其复制到位于外表单标签的隐藏元素并用一个虚拟字符替换索引器的所有实例,因此 name =TargetInfo [0] .TargetColor_U
变为 name =TargetInfo [#]。 TargetColor_U
),并且替换隐藏输入的值
属性,因此 value =0
变成 value =#
< table id =newrowstyle =display:none>
.... //复制tr元素及其内容
< / table>
然后脚本会像
var form = $('form'); //或者使用id,如果你给出了一个id
var newrow = $('#newrow');
var tablebody = $('#tablebody'); //修改以适应您的id
$(#btnAddTarget)。click(function(){
var index =(new Date())。getTime(); // unique indexer
var clone = newrow.clone(); //克隆新行
clone.html($(clone).html()。replace(/#/ g,index));克隆
var row = clone.find('tr');
tablebody.append(row); //将新行添加到表
// Reparse验证器
form.data('validator',null);
$ .validator.unobtrusive.parse(form);
});
附注:
- 不显眼的验证通过在首次呈现表单时解析
data-val
属性
。当您添加动态内容时,如脚本的最后两行
中所示,需要
才能重新解析验证器。 - 添加隐藏索引器的输入允许您
删除集合中的任何行,因此删除删除按钮是
不再是必要的,并且将给用户更好的体验。 - 而是使用内联样式,而不是
< td style =padding-left:0px; padding-top:0px; padding-bottom:0px; padding- right:0px>
,你应该使用#table td {padding:0; }
- 在
.css
文件中添加行纯粹的客户端提供了最佳性能,
其难以维护。如果您在属性上添加或更改任何验证
属性(例如,您可能稍后添加
[StringLength]
属性),则需要将html更新为
。或者,您可以考虑使用
BeginCollectionItem 帮助程序,这意味着您有一个部分
视图(表示表行)。对于现有项目,您使用
foreach
循环@ Html.Partial()
,您使用ajax
调用返回部分视图的控制器方法,
更新DOM
I have a table that have a row of dynamic textbox. Example below:
I add the row in the table by clicking the [+] Add New Target a it below screen will appear:
I want to add validation class to all text box inside the table. So when the user click the save button, it will check all the text box.
I try to use this jquery to this:
$('#tbTargetDetails tr').each(function () {
$(this).find('td input:text').each(function (i,a) {
// get each of the textbox and add validation class to it
});
});
I'm using MVC 5, jquery-1.10.2.js, jquery-1.10.2.min.js, jquery.validate* & Site.css that have class input.input-validation-error
In my models:
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; }
}
I call above model inside another model:
public class abc
{
public IList<ClsTargetInfo> TargetInfo { get; set; }
}
Below is the code when i adding the new row:
$("#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="/Content/images/trashcan.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);
}
Please help to solve my issue. Really appreciate your guys help. Thank you.
You are not including the necessary data-val
attributes to the textboxes, or the placeholder elements for displaying the validation messages, which are used by jquery.validate.unobtrusive.js
to do client side validation. In addition, your current implementation does not allow the user to remove anything other that the last row which can be solved by including a hidden input for the indexer which allows non consecutive indexers to be posted and bound to your collection.
First start by adding one default ClsTargetInfo
object to your TargetInfo
property and generate its html in the view
<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>
Then inspect the html it generates for the <tr>
element which should look something like
<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>
and copy it inside a hidden element that is placed outside the form tags and replace all instance of the indexer with a dummy character so name="TargetInfo[0].TargetColor_U"
becomes name="TargetInfo[#].TargetColor_U"
), and also replace the value
attribute of the hidden input so value="0"
it becomes value="#"
<table id="newrow" style="display:none">
.... // copy the tr element and its contents here
</table>
Then the script will look like
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);
});
Side notes:
- Unobtrusive validation works by parsing the
data-val
attributes when the form is first rendered. When you add dynamic content, it is necessary to re-parse the validator as indicated in the last 2 lines of the script. - The addition of the hidden input for the indexer allows you to delete any row in the collection, so removing the "delete" button is no longer necessary and will give the user a better experience.
- Rather that using inline styles, use css instead, for example, rather than
<td style="padding-left:0px;padding-top:0px;padding-bottom:0px;padding-right:0px">
, you should use#table td { padding: 0; }
in your.css
file - While adding the rows purely client side gives the best performance,
its difficult to maintain. If you add or change any validation
attributes on your properties (for example you might later add a
[StringLength]
attribute), you will need to update the html to suit. As an alternative, you can consider using the BeginCollectionItem helper which means you have one partial view (representing a table row). For existing items, you use aforeach
loop with@Html.Partial()
and for new rows, you use ajax to call a controller method that return a the partial view, and update the DOM
这篇关于在表中设置动态文本框的类验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!