如何用jQuery Ajax实现动态表格行下拉框联动填充同行字段
解决动态新增行下拉框联动填充当前行字段的问题
这个问题我之前也碰到过,核心原因是你用了唯一的ID选择器处理动态生成的多行元素——当新增行后,页面上会出现多个相同ID的元素,jQuery只会匹配第一个,所以切换后面行的下拉选项时,会修改第一行的字段。下面给你一步步解决的方案:
第一步:将ID选择器替换为类选择器
首先修改HTML里的表单元素,把重复行中会用到的id属性改成class,因为class可以在多个元素上重复使用,适合动态行场景:
<?php echo form_open_multipart(base_url().'back/transaksi/Order/insert_temp', array('role' => 'form', 'class' => 'form-horizontal', 'method'=>'POST','id'=>'Validation_form'));?> <fieldset style="min-width: 0;padding:.35em .625em .75em!important;margin:0 2px;border: 2px solid black!important;margin-bottom: 10em;"> <legend style="border-bottom: none;width: inherit !important; padding:inherit; font-weight:bold; color:red;">Form Input</legend> <button class="btn btn-success add_field_button" type="button" onClick="addRow('dataTable')">Add </button> <input type="button" class="btn btn-danger" value="Remove Field" onClick="deleteRow('dataTable')"/> <div> </div> <table id="dataTable" class="table table-striped table-responsive table-bordered dataTable" width="100%"> <thead> <tr> <th><input type="checkbox" id="selectall" value="selectAll"/></th> <th class="text-center">No</th> <th class="text-center">Item</th> <th class="text-center">Konversi</th> <th class="text-center">Spesifikasi</th> <th class="text-center">qty</th> <th class="text-center">Satuan</th> <th class="text-center">Note</th> </tr> </thead> <tbody> <tr> <td><input type="checkbox" class="check"></td> <td class="no"> </td> <td> <select name="id_komoditi[]" class="form-control chzn_select_L id_komoditi"> <option value="">--- Pilih Item ---</option> <?php foreach($id_komoditi as $a) { echo "<option value='".$a['id_komoditi']."'>".$a['nama_komoditi']."</option>"; } ?> </select> </td> <div class="input_fields_wrap1"> <div><input type="hidden" name="id_order[]" class="id_order" value="<?php echo $_GET['id'];?>"></div> </div> <div class="input_fields_wrap"> <div><input type="hidden" name="item[]" class="item"></div> </div> <td> <select name="id_konversi_satuan[]" class="form-control chzn_select_R id_konversi_satuan"> <option value="">--- Pilih Konversi ---</option> <?php foreach($id_konversi_satuan as $a) { echo "<option value='".$a['id_konversi_satuan']."'>".$a['satuan_awal']."</option>"; } ?> </select> </td> <td><input name="spesifikasi[]" type="text" class="form-control spesifikasi"></td> <td><input name="qty[]" type="text" class="form-control qty"></td> <td><input name="satuan[]" type="text" class="form-control satuan"></td> <td><textarea name="note[]" type="text" class="form-control note"></textarea></td> </tr> </tbody> </table> <button style="border-radius: 3px; box-shadow: 0 3px 6px rgba(0,0,0,0.9);" type="submit" class="btn btn-success">Entry</button> </fieldset> </form>
第二步:修改联动逻辑,使用事件委托并定位当前行
因为动态新增的行是后来生成的,直接绑定事件不会生效,所以要使用事件委托,同时通过closest('tr')定位到当前下拉框所在的行,再填充该行对应的字段:
$(document).ready(function(){ dataTable(); $('#selectall').click(function(event) { if(this.checked) { $('.check').each(function() { this.checked = true; }); } else { $('.check').each(function() { this.checked = false; }); } }); // 使用事件委托绑定change事件,处理动态生成的下拉框 $(document).on('change', '.id_komoditi', function(){ var $currentRow = $(this).closest('tr'); // 获取当前下拉框所在的行 $.ajax({ url: '<?=base_url();?>back/transaksi/Order/Detail_Item', method: 'POST', data:{ id_komoditi: $(this).val(), // 当前下拉框的值 }, dataType:'json', success:function(hasil) { // 填充当前行的spesifikasi字段 $currentRow.find('.spesifikasi').val(hasil.spesifikasi); // 如果还有其他需要填充的字段,比如satuan,也可以在这里处理: // $currentRow.find('.satuan').val(hasil.satuan); } }); }); });
第三步:确保动态新增行的元素正确初始化
你的新增行代码已经在复制第一行的HTML,只要第一行的元素都改成了class,新增的行就会自动继承这些class。另外注意Chosen插件的初始化,你的现有代码已经处理了新增行后的Chosen销毁和重新初始化,这部分可以保留,同时补充序号更新逻辑(可选):
function addRow(dataTable){ var table = document.getElementById(dataTable); var rowCount = table.rows.length; if(rowCount < 301) { $(" .chzn_select_L").chosen('destroy'); $(" .chzn_select_R").chosen('destroy'); var row = table.insertRow(rowCount); var colCount = table.rows[1].cells.length; var wrapper = $(" .input_fields_wrap"); var wrapper1 = $(" .input_fields_wrap1"); $(wrapper).append('<div><input type="hidden" name="item[]" class="item"/></div>'); $(wrapper1).append('<div><input type="hidden" name="id_order[]" class="id_order" value="<?php echo $_GET['id'];?>"/></div>'); for(var i=0; i<colCount; i++) { var newcell = row.insertCell(i); newcell.innerHTML = table.rows[1].cells[i].innerHTML; // 更新新增行的序号 if(i === 1){ newcell.textContent = rowCount; } } $(" .chzn_select_L").chosen(); $(" .chzn_select_R").chosen(); // 重新绑定所有行的序号(可选,避免删除行后序号混乱) updateRowNumbers(table); } else { alert('Maximum 300 rows allowed'); } } // 辅助函数:更新所有行的序号 function updateRowNumbers(table){ var rows = table.tBodies[0].rows; for(var i=0; i<rows.length; i++){ rows[i].cells[1].textContent = i+1; } }
关键原理说明
- 类选择器替代ID选择器:ID在HTML中必须唯一,动态生成多行时重复ID会导致选择器失效;class可以重复,适合批量处理相同类型的元素。
- 事件委托:
$(document).on('change', '.id_komoditi', ...)会监听整个文档的change事件,只要触发事件的元素匹配.id_komoditi类,就会执行回调,即使元素是动态生成的也能生效。 - 定位当前行:
$(this).closest('tr')可以精准找到当前下拉框所在的表格行,确保填充的是当前行的字段,而不是其他行的。
内容的提问来源于stack exchange,提问作者epm.007
相关产品推荐
相关产品推荐

