jQuery添加表格行时访问父元素取上一行Serial End值为新行Serial Start加1赋值遇undefined
问题根源定位
你始终获取到undefined的核心原因有4个:
- 元素选择路径完全错位:你给
#addrow按钮绑定的第二个点击回调里,错误用$(this).parent('tr')找父级表格行,但实际#addrow按钮是在表格外的表单区域,根本不在<tr>标签内部,顺着这个路径找任意子元素自然拿不到值,返回undefined。 - 业务逻辑完全偏离需求:你原本的代码全程用隐藏域
#start存自增的行索引,根本没有实现「取上一行Serial End输入值+1填到新行Serial Start」的逻辑,相当于完全走了另一套分支。 - 初始HTML有语法错误:表格第一行
tablerow_0里的Serial End输入标签没有正确闭合,部分场景下会导致DOM元素解析异常。 - 重复绑定了
#addrow的点击事件,两个回调同时触发会互相干扰执行流程。
修正后的实现逻辑
- 单一定义
#addrow的点击事件,删除冗余的重复绑定代码 - 新建行之前,先判断当前已有的最后一行(包括页面最上方独立的初始Serial End输入框)的Serial End值:
- 如果是第一次加表格行,取页面顶部独立的
#serend输入框的数值 - 如果是后续加行,取tbody里最后一行的
serend[]输入框的数值
- 如果是第一次加表格行,取页面顶部独立的
- 把取到的Serial End值+1之后,直接填充到新行的
serstart[]输入框里 - 修正HTML标签的闭合错误,统一表格行数判断逻辑
核心修正代码片段
$(document).ready(function() { const MAX_ROW = 5; // 最大行数限制 // 单一定义addrow的点击事件,避免重复绑定 $("#addrow").on("click", function() { const rowCount = $("#tbl tr").length; if (rowCount >= MAX_ROW) { alert("It is limited for 5 rows only"); return; } // 1. 获取上一行的Serial End值 let lastSerialEnd; if (rowCount === 0) { // 第一行取页面顶部独立的Serial End输入值 lastSerialEnd = parseInt($("#serend").val().trim()) || 0; } else { // 后续行取tbody最后一行的Serial End输入值 lastSerialEnd = parseInt($("#tbl tr").last().find("input[name='serend[]']").val().trim()) || 0; } const newSerialStart = lastSerialEnd + 1; // 2. 获取当前新行的索引 const newRowIndex = parseInt($("#start").val()); // 3. 构建新行 const newRow = $(`<tr id='tablerow_${newRowIndex}'>`); const cols = ` <td> <select onchange="selectmodel(this)" data-live-search="true" placeholder="Select your model name" id="model${newRowIndex}" class="form-control selectpicker show-menu-arrow" name="model[]"> <option selected disabled> Select your model name</option> <?php $sql = mysqli_query($con,"call gettrial"); if(mysqli_num_rows($sql)>0){ while($row=mysqli_fetch_assoc($sql)){ echo "<option value='{$row['id']}'>{$row['model_name']}</option>"; } } ?> </select> </td> <td><input id="code${newRowIndex}" value="" type="text" class="form-control" name="code[]" readonly /></td> <td><input type="number" class="form-control" id="serstart${newRowIndex}" name="serstart[]" readonly value="${newSerialStart}" /></td> <td><input type="number" class="form-control" id="serend${newRowIndex}" name="serend[]" onkeyup="manage(this)" /></td> `; newRow.append(cols); $("table.order-list tbody").append(newRow) .find('.selectpicker') .selectpicker({ liveSearch: true, showSubtext: true }); // 更新隐藏域的行索引值 $("#start").val(newRowIndex + 1); }); // 删除行逻辑 $('#remove').click(function() { const tbody = $("#myTable tbody"); if (tbody.find("tr").length > 0) { tbody.find("tr:last").remove(); } }); });
配套修正的HTML片段
<tbody id='tbl'> <tr id="tablerow_0"> <td> <select name="model[]" id="model0" class="form-control selectpicker show-menu-arrow" data-live-search="true" title="Select your model name" onchange="selectmodel(this)" required> <?php $sql = mysqli_query($con,"SELECT model.id,model.model_name,model.code,model.status FROM model left join grouped on model.id = grouped.modelandcode WHERE cat_id='1' and model.status='1' and grouped.status is null ORDER BY model_name ASC"); $con->next_result(); if(mysqli_num_rows($sql)>0) { while($row=mysqli_fetch_assoc($sql)) { echo "<option value='".$row['id']."'>".$row['model_name']."</option>"; } } ?> </select> </td> <td> <input name="code[]" type="text" id="code0" value="" class="form-control" readonly /> </td> <td> <input type="number" name="serstart[]" id="serstart0" class="form-control" readonly /> </td> <td> <!-- 修正了未闭合的input标签 --> <input type="number" name="serend[]" id="serend0" class="form-control" /> </td> </tr> </tbody>
注意点:如果第一行的Serial Start需要和页面顶部独立的Serial Start输入值联动,你可以在初始化时手动给
#serstart0赋值,逻辑和上面取Serial End的逻辑保持一致即可。
内容的提问来源于stack exchange,提问作者user14716889
相关产品推荐
相关产品推荐

