动态增删行表格中Autocomplete功能失效问题排查
动态表格行Autocomplete失效问题修复
问题根源
- 重复ID冲突:动态生成的输入框使用固定ID(如
barcodeSearch),HTML中ID必须唯一,导致新行的Autocomplete无法正确绑定,且选择事件会错误修改第一行内容。 - HTML语法错误:动态生成的input标签存在未闭合、引号缺失问题,导致DOM结构异常。
- 初始行未初始化Autocomplete:默认第一行的输入框未绑定Autocomplete事件。
- 全局选择器错误:Autocomplete的
select事件中使用全局ID选择器,无法定位当前行的对应输入框。
修复步骤及代码
1. 统一使用类选择器,移除重复ID
将所有动态元素的ID替换为类名,确保每行元素通过类名在当前行上下文查找。
2. 修正HTML语法错误
补全动态生成标签的引号和闭合部分。
3. 封装Autocomplete初始化函数
将Autocomplete的初始化逻辑封装成函数,方便初始行和新增行调用。
4. 调整select事件的元素定位
使用$(this).closest('tr')获取当前行,再通过类名查找该行内的输入框进行赋值。
修正后的完整代码
HTML部分
<table class="table table-bordered table-hover" id="tab_logic"> <thead class="table-success"> <tr> <th class="text-center">Barcode</th> <th class="text-center">Code</th> <th class="text-center">Stock In Hand</th> <th class="text-center">Stock Out Qty</th> <th class="text-center">Balance Qty</th> </tr> </thead> <tbody> <tr> <td> <input class="form-control barcode-search" name="barcode[]" type="text" placeholder="Search By barcode" autocomplete="off"> </td> <td> <input type="text" class="form-control product-name" readonly /> <input type="hidden" class="form-control product-id" name="product_id[]" /> </td> <td> <input type="number" class="form-control balance-qty" readonly /> </td> <td> <input type="number" name="quantity[]" class="form-control stockout-qty balance-check" required /> </td> <td> <div class="input-group"> <input type="number" name="subTotal[]" class="form-control stock-balance" readonly /> <div class="ibtnDel input-group-btn"> <button class="btn btn-danger" type="button"> <i class="fa fa-minus" aria-hidden="true"></i> </button> </div> </div> </td> </tr> </tbody> </table> <div class="col-md-12"> <p class="pull-left">for new row press enter</p> <button id="add_row" class="btn btn-success pull-right"> <i class="fa fa-plus" aria-hidden="true"></i> </button> </div> <div class="col-md-12"> <input class="btn btn-success pull-right" type="submit" value="Submit"> </div>
JavaScript部分
$(document).ready(function() { var counter = 0; // 封装Autocomplete初始化函数 function initAutocomplete($input) { $input.autocomplete({ source: function(request, response) { $.ajax({ url: "{{route('getBarcodes')}}", type: 'post', dataType: "json", data: { _token: CSRF_TOKEN, search: request.term }, success: function(data) { response(data); } }); }, select: function(event, ui) { var $row = $(this).closest('tr'); // 给当前行的元素赋值 $row.find('.barcode-search').val(ui.item.label); $row.find('.product-id').val(ui.item.product_id); $row.find('.product-name').val(ui.item.productCode); $row.find('.balance-qty').val(ui.item.balanceQty); return false; } }); } // 初始化第一行的Autocomplete initAutocomplete($('.barcode-search')); $("#add_row").on("click", function(e) { e.preventDefault(); var newRow = $("<tr>"); var cols = ""; // 修正HTML语法,使用类名代替ID cols += '<td><input type="text" placeholder="search by barcode" class="form-control barcode-search" name="barcode[]' + counter + '" /></td>'; cols += '<td><input type="text" placeholder="Price" class="form-control product-name" name="product_code_' + counter + '" readonly/></td>'; cols += '<input type="hidden" class="form-control product-id" name="product_id[]' + counter + '" />'; cols += '<td><input type="number" placeholder="Stock In Hand" class="form-control balance-qty" name="balance_qty_' + counter + '" readonly/></td>'; cols += '<td><input type="number" placeholder="Qty" class="form-control stockout-qty balance-check" name="quantity[]' + counter + '" /></td>'; cols += '<td><div class="input-group"><input type="number" class="form-control stock-balance" name="subTotal[]' + counter + '" readonly/><div class="ibtnDel input-group-btn"> <button class="btn btn-danger" type="button"><i class="fa fa-minus" aria-hidden="true"></i></button></div></div></td>'; newRow.append(cols); $("#tab_logic tbody").append(newRow); counter++; // 初始化新行的Autocomplete initAutocomplete(newRow.find('.barcode-search')); }); $("#tab_logic tbody").on("click", ".ibtnDel", function(e) { e.preventDefault(); $(this).closest("tr").remove(); calc(); }); $('#tab_logic tbody').on('keyup change', '.stockout-qty', function() { calc(); }); function calc() { $('#tab_logic tbody tr').each(function(i, element) { var $row = $(this); var balanceQty = parseInt($row.find('.balance-qty').val()) || 0; var stockoutQty = parseInt($row.find('.stockout-qty').val()) || 0; $row.find('.stock-balance').val(balanceQty - stockoutQty); calc_total(); }); } function calc_total() { var totalBalance = 0; $('.stock-balance').each(function() { var val = parseInt($(this).val()) || 0; totalBalance += val; }); // 可在此处添加总余额显示逻辑 } $(document).on('keyup', '.balance-check', function() { var totalBalanceQty = 0; $('.balance-qty').each(function() { var val = parseInt($(this).val()) || 0; totalBalanceQty += val; }); var $field = $(this); var balanceCheck = parseInt($field.val()) || 0; if (balanceCheck > totalBalanceQty) { swal({ title: 'Excess Quantity Enter!', type: "warning", text: 'Your Enter QTY Greater than Available QTY.', timer: 5000 }).then( function() {}, function(dismiss) { if (dismiss === 'timer') { console.log('I was closed by the timer') } } ); $field.val(""); } }); });
关键修复点说明
- 类代替ID:所有动态元素使用类名(如
barcode-search、product-name),避免ID重复导致的选择器冲突。 - 上下文查找:在
select事件中通过closest('tr')获取当前行,再用类名查找该行内的元素,确保赋值正确对应到当前行。 - 封装初始化函数:将Autocomplete逻辑封装,初始行和新增行统一调用,避免代码重复。
- 修正语法错误:补全动态生成标签的引号和闭合,确保DOM结构正确。
内容的提问来源于stack exchange,提问作者Imran Hosen
相关产品推荐
相关产品推荐

