DataTable中a标签按钮无法获取对应行正确ID的技术求助
我已经做了多方排查,但可能还有疏漏。现在我用PHP循环填充DataTable,每行都会显示记录ID、取消按钮和发票按钮(用a标签实现),同时还加了一个id="ID"的隐藏输入框来存储该行的记录ID;表格设置每页显示3条数据,支持分页。但现在遇到个问题:点击某行的发票按钮时,获取到的ID始终是当前页第一行的ID(比如当前页行ID是10、11、12,点击12行的按钮还是返回10),这个ID是用来构建跳转URL的,必须获取对应行的正确ID。我怀疑是所有隐藏输入框的id都设成"ID"导致的问题,想请大家帮忙排查错误原因。
相关代码
表格行ID展示代码
<td style="color: #0d9b84; text-align: center; width: 30px;"><?php echo "#".$part_result->ID; ?></td>
隐藏输入框代码
<input type="hidden" id="ID" value="<?php echo $part_result->ID;?>" />
发票按钮a标签代码
<a href="#" onclick="getadvertprice(); gotourlinvoice();" class="btn btn-success btn-block" style="color: #4cff00;">Invoice To Client<i class="fa fa-angle-right"></i></a>
JavaScript处理代码
<script type="text/javascript"> String.prototype.trim = function () { return this.replace(/^\s+|\s+$/g, ""); } function gotourlinvoice() { var url = "mynextpagehere.php"; var dataID = document.getElementById("ID").value; var partnumber = document.getElementById("partnumber").value; var partname = document.getElementById("partname").value; var invoicenumber = prompt("Please enter your DMS Invoice Number:", "Required: DMS Invoice Number"); if (invoicenumber == null || invoicenumber == "") { return; } else { datalinks = invoicenumber; } var parameters = { ID: dataID, PartNumber: partnumber, PartName: partname, InvoiceNumber: datalinks }; var fulllink = buildUrl(url, parameters); fulllink = encodeURIComponent(fulllink); alert("Your selection of record - ID: " + dataID + " has been saved as \"Invoiced\" with DMS Invoice Number - \"" + datalinks + "\""); alert(fulllink); //document.location.href = fulllink; } </script>
问题排查与解决方案
你猜的完全没错!问题的核心就是重复的id属性违反了HTML规范,具体原因和修复方法如下:
1. 问题根源:ID属性必须唯一
HTML标准明确要求,整个文档中的id属性值必须是唯一的。你通过PHP循环生成每行时,都创建了一个id="ID"的隐藏输入框,当调用document.getElementById("ID")时,浏览器只会返回第一个匹配到的元素——也就是当前页第一行的那个隐藏框,这就导致不管点击哪一行的按钮,拿到的都是第一行的ID。
2. 修复方案:给元素设置唯一ID并传递对应参数
我们可以通过以下几步修改代码来解决问题:
步骤1:修改隐藏输入框的ID,保证唯一性
把隐藏框的id改成包含当前记录ID的唯一值,比如:
<input type="hidden" id="ID_<?php echo $part_result->ID; ?>" value="<?php echo $part_result->ID;?>" />
这样每行的隐藏框id就会变成ID_10、ID_11、ID_12这类唯一值。
步骤2:修改按钮的点击事件,传递当前行的记录ID
修改a标签的onclick属性,把当前行的记录ID作为参数传给gotourlinvoice函数:
<a href="#" onclick="getadvertprice(); gotourlinvoice(<?php echo $part_result->ID; ?>);" class="btn btn-success btn-block" style="color: #4cff00;">Invoice To Client<i class="fa fa-angle-right"></i></a>
步骤3:修改JavaScript函数,接收并使用传递的ID
更新gotourlinvoice函数,通过传递的ID拼接出唯一的隐藏框id,再获取对应的值:
function gotourlinvoice(recordID) { var url = "mynextpagehere.php"; // 通过拼接的唯一ID获取对应隐藏框的值 var dataID = document.getElementById("ID_" + recordID).value; var partnumber = document.getElementById("partnumber").value; var partname = document.getElementById("partname").value; var invoicenumber = prompt("Please enter your DMS Invoice Number:", "Required: DMS Invoice Number"); if (invoicenumber == null || invoicenumber == "") { return; } else { datalinks = invoicenumber; } var parameters = { ID: dataID, PartNumber: partnumber, PartName: partname, InvoiceNumber: datalinks }; var fulllink = buildUrl(url, parameters); fulllink = encodeURIComponent(fulllink); alert("Your selection of record - ID: " + dataID + " has been saved as \"Invoiced\" with DMS Invoice Number - \"" + datalinks + "\""); alert(fulllink); //document.location.href = fulllink; }
3. 更简洁的替代方案(可选)
其实我们完全可以去掉隐藏输入框,直接把记录ID作为参数传递给函数,省去DOM查询的步骤:
- 修改a标签:
<a href="#" onclick="getadvertprice(); gotourlinvoice(<?php echo $part_result->ID; ?>);" class="btn btn-success btn-block" style="color: #4cff00;">Invoice To Client<i class="fa fa-angle-right"></i></a>
- 简化JavaScript函数:
function gotourlinvoice(dataID) { var url = "mynextpagehere.php"; var partnumber = document.getElementById("partnumber").value; var partname = document.getElementById("partname").value; var invoicenumber = prompt("Please enter your DMS Invoice Number:", "Required: DMS Invoice Number"); if (invoicenumber == null || invoicenumber == "") { return; } else { datalinks = invoicenumber; } var parameters = { ID: dataID, PartNumber: partnumber, PartName: partname, InvoiceNumber: datalinks }; var fulllink = buildUrl(url, parameters); fulllink = encodeURIComponent(fulllink); alert("Your selection of record - ID: " + dataID + " has been saved as \"Invoiced\" with DMS Invoice Number - \"" + datalinks + "\""); alert(fulllink); //document.location.href = fulllink; }
这样代码更简洁,也避免了DOM查询可能带来的问题。
内容的提问来源于stack exchange,提问作者AlwaysConfused

