You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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);
});

问题原因及修复方案

核心问题点

  1. 索引获取逻辑错误:match(/\d+/)返回的是数组,直接拼接会导致name属性格式混乱,比如变成[0,1].ProjectsList
  2. 隐藏字段赋值错误:用$("#id")通过ID选择元素,但新增行的元素只有class没有ID,会一直修改第一行的隐藏字段值
  3. 动态元素事件缺失:新增行的删除按钮没有绑定事件,且克隆元素可能保留旧状态导致冲突
  4. 表头行干扰:克隆时会把表头行也算进去,导致索引计算错误

修复后的完整代码

优化后的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:49:50