Chosen插件在HTML表格动态生成行中失效问题求助
Chosen插件动态克隆行下拉失效问题解决
我用Chosen插件实现表格首行的下拉筛选功能,正常工作。但动态克隆生成新行后,下拉列表失效,且所有新行都显示首行的选中值。相关代码如下:
原HTML代码
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Medicine Re-Location Form</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"> <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.min.js"></script> <link rel = "stylesheet" href = "https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.min.css"> </head> <body> <div class="container"> <div class="card"> <h3 div class="card-header" style="background-color: #3fbbc0;">Request Form</h3> <div class="card-body"> <form method="POST" action="invoice.php"> <table class="table table-bordered"> <thead class="table-success" style="background-color: #3fbbc0;"> <tr> <th width="15%"><center>Product</th> <th width="10%"><center>Qty (No)</th> <th width="20%"><center>Remarks</th> <th width="5%"></th> <button type="button" class="btn btn-sm btn-success" onclick="BtnAdd()">Add Item</button> </th> </tr> </thead> <tbody id="TBody"> <tr id="TRow" > <td><Select class="scode form-control text-end" name="scode[]" id = "scode" class="form-control" required onchange="GetDetail(this.closest('tr'))"> <option value="">Select Product</option> <?php include('db.php'); $sql = mysqli_query($con,"SELECT * FROM procd2"); while($row=mysqli_fetch_array($sql)) { echo '<option value="'.$row['pro1'].'">'.$row['pro1'].'</option>'; } ?></select> </td> <td><input type="text" class="qty form-control text-end" name="qty[]" id="ccc" pattern="\d+"></td> <td><input type="text" class="form-control text-end" name="remarks3[]" id="zzz" ></td> <td class="NoPrint"><button type="button" class="btn btn-success" style="line-height: 1;" onclick="BtnDel(this)">x</button></td> </tr> </tbody> </table> <script> jQuery('.scode').chosen(); </script> <div class="col-lg-4"> <div class="form-group"><center> <input type="submit" name="submit" id="submit" value="Submit" class="btn btn-success submit_btn invoice-save-btm"> </form>
原JavaScript代码
function GetPrint() { /*For Print*/ window.print(); } function BtnAdd() { /*Add Button*/ var v = $("#TRow").clone().appendTo("#TBody") ; $(v).find("input").val(''); $(v).find("select.scode").chosen(); $(v).removeClass("d-none"); $(v).find("th").first().html($('#TBody tr').length - 1); } function BtnDel(v) { /*Delete Button*/ $(v).parent().parent().remove(); GetTotal(); $("#TBody").find("tr").each( function(index) { $(this).find("th").first().html(index); } ); } function Calc(v) { /*Detail Calculation Each Row*/ var index = $(v).parent().parent().index(); var qqq1 = document.getElementsByName("qty[]")[index].value; GetTotal(); } function GetTotal() { /*Footer Calculation*/ var sum=0; var amts = document.getElementsByName("tot4[]"); for (let index = 0; index < amts.length; index++) { var tot4 = amts[index].value; sum = +(sum) + +(tot4) ; } document.getElementById("totbil").value = sum; var gst = document.getElementById("adv11").value; var net = +(sum) - +(gst); document.getElementById("netpayable1").value = net; }
问题原因分析
- 模板行的表单元素带有固定ID(如
scode、ccc),克隆后出现重复ID,引发DOM冲突; - 直接克隆已初始化Chosen的DOM元素,会携带原选中状态和Chosen生成的额外结构,导致新行继承旧状态;
- 初始化新行Chosen时,未清理原实例,造成绑定异常。
解决方案
1. 修改HTML模板行
移除所有重复ID,改用类选择器标记模板行:
<tbody id="TBody"> <tr class="TRow"> <!-- 将ID改为类 --> <td> <!-- 移除id="scode",保留类名scode --> <select class="scode form-control text-end" name="scode[]" required onchange="GetDetail(this.closest('tr'))"> <option value="">Select Product</option> <?php include('db.php'); $sql = mysqli_query($con,"SELECT * FROM procd2"); while($row=mysqli_fetch_array($sql)) { echo '<option value="'.$row['pro1'].'">'.$row['pro1'].'</option>'; } ?> </select> </td> <td> <!-- 移除id="ccc" --> <input type="text" class="qty form-control text-end" name="qty[]" pattern="\d+"> </td> <td> <!-- 移除id="zzz" --> <input type="text" class="form-control text-end" name="remarks3[]"> </td> <td class="NoPrint"> <button type="button" class="btn btn-success" style="line-height: 1;" onclick="BtnDel(this)">x</button> </td> </tr> </tbody>
2. 修改BtnAdd函数
克隆前销毁模板行的Chosen实例,重置新行表单状态,再重新初始化:
function BtnAdd() { // 获取模板行并克隆 var templateRow = $(".TRow").first().clone(); // 销毁模板行的Chosen实例,恢复原生select $(".TRow .scode").chosen('destroy'); // 清空新行input值 templateRow.find("input").val(''); // 重置新行select为默认选项 templateRow.find("select.scode").val('').prop('selectedIndex', 0); // 将新行添加到表格 templateRow.appendTo("#TBody"); // 重新初始化模板行的Chosen $(".TRow .scode").chosen(); // 初始化新行的Chosen templateRow.find("select.scode").chosen(); // 更新行号(如果需要) templateRow.find("th").first().html($('#TBody tr').length - 1); }
说明
- 销毁模板行的Chosen是为了确保克隆的是原生select,避免携带旧状态;
- 移除重复ID可避免DOM操作时的冲突问题;
- 重置select选中值保证新行默认显示“Select Product”选项。
内容的提问来源于stack exchange,提问作者Student
相关产品推荐
相关产品推荐

