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

AJAX动态填充HTML下拉框问题:新增行后联动失效

问题分析与解决方案

我看了你的代码,问题主要出在重复ID使用和目标元素定位错误上,这是动态添加表单行时非常常见的坑。咱们一步步拆解并修复:

核心问题点

  1. ID重复:你在动态生成的每一行里都用了id="course"和id="branch",但HTML中ID必须是唯一的。这会导致事件绑定混乱,选择器无法精准定位到当前行的元素。
  2. 分支选择器错误:在AJAX回调里,你用$("td").siblings("td").children("#branch").html(html),这会修改页面上所有的#branch元素,而不是当前选中课程所在行的分支下拉框。
  3. 禁用分支的逻辑错误:当没有分支数据时,你禁用了所有#branch,而不是当前行的那个。

修复后的代码

1. 修改JS代码

// 删除行的逻辑保持不变
$('#myTable').on('click', 'input[type="button"]', function () { 
    $(this).closest('tr').remove(); 
})

// 动态生成行的HTML,把ID换成CLASS,避免重复
var html = "";
html += '<tr>';
html += '<td><select class="form-control course-select" name="course[]" style="width: 200px">';
html += '<option value="">--SELECT COURSE --</option>';
html += '<?php foreach ($courseList as $key => $value) { ?>';
html += '<option value="<?php echo $value['id']; ?>"><?php echo $value['c_name']; ?></option>';
html += '<?php } ?>';
html += '</select>';
html += '</td>';
html += '<td><select class="form-control branch-select" name="branch[]" style="width: 200px"></select>';
html += '</td>';
html += '<td><input type="number" class="form-control" name="course_fee[]" placeholder="Course Fee" autocomplete="off" required=""></td>';
html += '<td><input type="number" class="form-control" name="discount_per[]" placeholder="Discount Percent" autocomplete="off" required=""></td>';
html += '<td><input type="number" class="form-control" name="total_seats[]" placeholder="Total Seats" autocomplete="off" required=""></td>';
html += '<td><input type="text" class="form-control stime" name="start_session[]" placeholder="Start Session" autocomplete="off" required=""></td>';
html += '<td><input type="text" class="form-control etime" name="end_session[]" placeholder="End Session" autocomplete="off" required=""></td>';
html += '<td>';
html += '<input type="button" class="btn btn-danger" value="Delete" />';
html += '</td>';
html += '</tr>';

// 添加行的逻辑保持不变
$('p input[type="button"]').click(function () { 
    $('#myTable').append(html); 
});

// 修改事件绑定为class选择器,确保动态添加的元素也能触发
$(document).on('change', '.course-select', function () { 
    fetch_select(this); 
})

function fetch_select(val) {
    // 获取当前课程选择框所在的行
    var currentRow = $(val).closest('tr');
    // 获取当前行对应的分支选择框
    var branchSelect = currentRow.find('.branch-select');

    $.ajax({
        type: 'post',
        url: 'common/ajax.function.php',
        data: { course_id: val.value, course: "select_course" },
        success: function (response) {
            var html = "";
            var data = JSON.parse(response);
            
            if (data !== '') {
                $.each(data, function (key, value) {
                    html += '<option value="' + value['id'] + '">' + value['branch_name'] + '</option>';
                });
                // 启用分支选择框
                branchSelect.prop("disabled", false);
            } else {
                // 禁用当前行的分支选择框
                branchSelect.prop("disabled", true);
            }
            // 只更新当前行的分支选择框内容
            branchSelect.html(html);
        }
    });
}

2. 修改PHP中的静态行代码

把初始行里的id="course"和id="branch"也换成对应的class:

<table id="myTable" class="data datatable table table-striped table-bordered table-hover" id="institution">
<thead>
<tr>
<th style="width:0px">Course</th>
<th>Branch</th>
<th>Course Fee</th>
<th>Discount Percent</th>
<th>Total Seats</th>
<th>Start Session</th>
<th>End Session</th>
</tr>
</thead>
<tbody>
<tr>
<td><select class="form-control course-select" name="course[]" style="width: 200px" >
<option value="">--SELECT COURSE --</option>
<?php foreach ($courseList as $key => $value) { ?>
<option value="<?php echo $value['id']; ?>"><?php echo $value['c_name']; ?></option>
<?php } ?>
</select>
</td>
<td ><select class="form-control branch-select" name="branch[]" style="width: 200px">
</select></td>
<td><input type="number" class="form-control" name="course_fee[]" placeholder="Course Fee" autocomplete="off" required=""></td>
<td><input type="number" class="form-control" name="discount_per[]" placeholder="Discount Percent" autocomplete="off" required=""></td>
<td><input type="number" class="form-control" name="total_seats[]" placeholder="Total Seats" autocomplete="off" required=""></td>
<td><input type="text" class="form-control stime" name="start_session[]" placeholder="Start Session" autocomplete="off" required=""></td>
<td><input type="text" class="form-control etime" name="end_session[]" placeholder="End Session" autocomplete="off" required=""></td>
<td>
<input type="button" class="btn btn-danger" value="Delete" />
</td>
</tr>
</tbody>
</table>
<br>
<p style="float: right">
<input type="button" value="Insert row &darr;">
</p>

关键修改说明

  • 替换ID为CLASS:用.course-select和.branch-select代替原来的ID,避免DOM中重复ID的问题,同时方便通过class选择器定位元素。
  • 精准定位当前行元素:在fetch_select函数里,先通过$(val).closest('tr')找到当前课程选择框所在的行,再用find('.branch-select')获取该行的分支选择框,确保只修改当前行的内容。
  • 修正禁用逻辑:只禁用当前行的分支选择框,而不是全局所有。
  • 事件委托适配动态元素:事件绑定在document上,用class选择器,确保动态添加的行也能触发change事件。

这样修改后,不管添加多少行,每一行的课程和分支都能独立联动,不会互相干扰了。

内容的提问来源于stack exchange,提问作者Sanjit Bhardwaj

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:14