使用jQuery动态添加行时Select元素功能异常求助
动态添加含Select的表单行后jQuery功能失效问题
我的表单包含input和select字段,点击「Add New Row」按钮可动态添加行,但添加2个带select元素的行后,jQuery功能就停止工作了。试过用ViewBag传递下拉列表等方法,都没解决问题。相关代码如下:
View
<div style="width:700px; padding:5px; background-color:white;"> <form action="/SendDSR/AddDsr" method="post"> <input name="__RequestVerificationToken" type="hidden" value="UgokOCFRFUqBT7l2lHFCloLmDf6388pD7WwFMCyA2egHbAYjEVODbDx0r-jIClvtvELLq-zdTPB0C9e9ZM4wx3BrRwsqfWb2cZXZ72RHpQBqjW5-NRKRdMoND8Slii2BzEd02oITPVPCVBdBJezUTQ2" /> <button class="btn btn-md btn-primary" id="addBtn" type="button"> Add New Row </button> <table id="dataTable" border="0" cellpadding="0" cellspacing="0" class="table table-hover"> <tr> <th>Project</th> <th>Task</th> <th class="status">Status</th> <th></th> <th></th> <th></th> <th></th> </tr> <tr style="border:1px solid black"> <td> <select class="form-control proj" name="[0].ProjectsList"> <option value="1">MCY</option> <option value="2">TWM</option> <option value="3">KHL</option> <option value="4">PTS</option> </select> </td> <td><input class="form-control task" name="[0].Task" required="required" type="text" value="" /></td> <td> <select class="form-control stdrod" name="[0].Status"> <option selected="selected" value="Completed">Completed</option> <option value="InProgress">InProgress</option> <option value="ToDo">ToDo</option> <option value="Blocker">Blocker</option> </select> </td> <td><input class="id" data-val="true" data-val-number="The field UserId must be a number." data-val-required="The UserId field is required." name="[0].UserId" type="hidden" value="1" /></td> <td><input class="email" name="[0].Email" type="hidden" value="riyaz_shaikh@external.mckinsey.com" /></td> <td><input data-val="true" data-val-date="The field Date must be a date." name="[0].Date" type="hidden" value="2/2/2024 12:00:00 AM" /></td> <td></td> <td></td> </tr> <tbody id="tbody"></tbody> </table> </form> </div>
jQuery
$("#addBtn").click(function (e) { e.preventDefault(); var $tableBody = $("#dataTable"); var $trLast = $tableBody.find("tr:last"); var e = $(".email").val(); var id = $(".id").val(); var $trNew = $trLast.clone(); debugger; var suffix = $trNew.find(':input:first').attr('name').match(/\d+/); $trNew.find("td:last").html('<a href="#" class="remove btn btn-warning" id="delete">Remove</a>'); $.each($trNew.find(':input'), function (i, val) { // Replaced Name var oldN = $(this).attr('name'); var newN = oldN.replace('[' + suffix + ']', '[' + (parseInt(suffix) + 1) + ']'); $(this).attr('name', newN); //Replaced value var type = $(this).attr('type'); if (type.toLowerCase() == "text") { $("#id").attr('value', id); $("#email").attr('value', e); } // If you have another Type then replace with default value $(this).removeClass("input-validation-error"); }); $trLast.after($trNew); // Re-assign Validation var form = $("form") .removeData("validator") .removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(form); });
问题原因及修复方案
核心问题点
- 索引获取逻辑错误:
match(/\d+/)返回的是数组,直接拼接会导致name属性格式混乱,比如变成[0,1].ProjectsList - 隐藏字段赋值错误:用
$("#id")通过ID选择元素,但新增行的元素只有class没有ID,会一直修改第一行的隐藏字段值 - 动态元素事件缺失:新增行的删除按钮没有绑定事件,且克隆元素可能保留旧状态导致冲突
- 表头行干扰:克隆时会把表头行也算进去,导致索引计算错误
修复后的完整代码
优化后的jQuery代码
$("#addBtn").click(function (e) { e.preventDefault(); // 排除表头行,只取数据行的最后一行 var $trLast = $("#dataTable tr:not(:first)").last(); // 取初始行的固定值 var emailVal = $(".email").first().val(); var userIdVal = $(".id").first().val(); var dateVal = $("[name='[0].Date']").val(); var $trNew = $trLast.clone(); // 正确获取当前行的索引(取match数组的第一个元素转数字) var currentIndex = parseInt($trLast.find(':input:first').attr('name').match(/\d+/)[0]); var newIndex = currentIndex + 1; // 重置新行的输入状态 $trNew.find(".task").val(""); $trNew.find(".stdrod").val("Completed"); // 更新所有输入框的name属性 $trNew.find(':input').each(function () { var oldName = $(this).attr('name'); var newName = oldName.replace(`[${currentIndex}]`, `[${newIndex}]`); $(this).attr('name', newName); // 给新行的隐藏字段赋值 if ($(this).hasClass("id")) { $(this).val(userIdVal); } if ($(this).hasClass("email")) { $(this).val(emailVal); } if ($(this).attr('name') === `[${newIndex}].Date`) { $(this).val(dateVal); } $(this).removeClass("input-validation-error"); }); // 添加删除按钮(去掉重复ID) $trNew.find("td:last").html('<a href="#" class="remove btn btn-warning">Remove</a>'); $trLast.after($trNew); // 重新解析表单验证 var form = $("form") .removeData("validator") .removeData("unobtrusiveValidation"); $.validator.unobtrusive.parse(form); }); // 用事件委托处理动态添加的删除按钮 $(document).on("click", ".remove", function (e) { e.preventDefault(); $(this).closest("tr").remove(); // 删除后重新整理所有行的索引,避免提交时索引不连续 $("#dataTable tr:not(:first)").each(function(index) { $(this).find(':input').each(function() { var oldName = $(this).attr('name'); var newName = oldName.replace(/\[\d+\]/, `[${index}]`); $(this).attr('name', newName); }); }); });
View结构优化建议
把初始数据行放到tbody里,结构更规范:
<div style="width:700px; padding:5px; background-color:white;"> <form action="/SendDSR/AddDsr" method="post"> <input name="__RequestVerificationToken" type="hidden" value="UgokOCFRFUqBT7l2lHFCloLmDf6388pD7WwFMCyA2egHbAYjEVODbDx0r-jIClvtvELLq-zdTPB0C9e9ZM4wx3BrRwsqfWb2cZXZ72RHpQBqjW5-NRKRdMoND8Slii2BzEd02oITPVPCVBdBJezUTQ2" /> <button class="btn btn-md btn-primary" id="addBtn" type="button"> Add New Row </button> <table id="dataTable" border="0" cellpadding="0" cellspacing="0" class="table table-hover"> <thead> <tr> <th>Project</th> <th>Task</th> <th class="status">Status</th> <th></th> <th></th> <th></th> <th></th> </tr> </thead> <tbody id="tbody"> <tr style="border:1px solid black"> <td> <select class="form-control proj" name="[0].ProjectsList"> <option value="1">MCY</option> <option value="2">TWM</option> <option value="3">KHL</option> <option value="4">PTS</option> </select> </td> <td><input class="form-control task" name="[0].Task" required="required" type="text" value="" /></td> <td> <select class="form-control stdrod" name="[0].Status"> <option selected="selected" value="Completed">Completed</option> <option value="InProgress">InProgress</option> <option value="ToDo">ToDo</option> <option value="Blocker">Blocker</option> </select> </td> <td><input class="id" data-val="true" data-val-number="The field UserId must be a number." data-val-required="The UserId field is required." name="[0].UserId" type="hidden" value="1" /></td> <td><input class="email" name="[0].Email" type="hidden" value="riyaz_shaikh@external.mckinsey.com" /></td> <td><input data-val="true" data-val-date="The field Date must be a date." name="[0].Date" type="hidden" value="2/2/2024 12:00:00 AM" /></td> <td></td> <td></td> </tr> </tbody> </table> </form> </div>
内容的提问来源于stack exchange,提问作者Rezo
相关产品推荐
相关产品推荐

