jQuery:为含多输入框的克隆行修改name属性内的数字
解决表单克隆时name/ID属性递增的问题
我懂你现在的痛点——克隆首行时行号能正常递增,但表单里的文本框、选择框的name、ID还有相关的data-*属性没跟着更新索引,导致提交表单时这些克隆字段的标识还是旧的,没法正确区分。其实这是因为克隆只是原样复制DOM结构,不会自动替换属性里的动态值,得手动遍历修改每个表单元素的相关属性才行。
下面给你一套具体的实现方案,直接就能用:
核心思路
- 先计算新行的索引(基于当前已有的行数)
- 深度克隆首行模板
- 遍历克隆行内的所有表单元素,把属性里的旧索引(比如
0)替换成新的索引值 - 处理行号显示的元素,避免ID重复
- 把修改好的克隆行添加到表单里
代码实现
假设你的克隆按钮ID是cloneButton,表格的行都有DB1_ROW类,直接把这段JS代码加到页面里就行:
document.getElementById('cloneButton').addEventListener('click', function() { // 获取首行模板 const masterRow = document.getElementById('CmasterRow'); // 计算新行的索引:现有行数就是新索引(初始行是0,第二行就是1,以此类推) const existingRows = document.querySelectorAll('.DB1_ROW').length; const newIndex = existingRows; // 深度克隆首行(true表示复制所有子元素和事件) const clonedRow = masterRow.cloneNode(true); // 修改克隆行的ID,避免重复 clonedRow.id = `CmasterRow_${newIndex}`; // 处理行号的span元素,修改ID避免重复 const cnumberSpan = clonedRow.querySelector('#cnumber'); if (cnumberSpan) { cnumberSpan.id = `cnumber_${newIndex}`; } // 遍历克隆行内所有的input和select元素 const formElements = clonedRow.querySelectorAll('input, select'); formElements.forEach(element => { // 更新ID属性:把所有[0]替换成[新索引] if (element.id) { element.id = element.id.replace(/\[0\]/g, `[${newIndex}]`); } // 更新name属性:同样替换索引 if (element.name) { element.name = element.name.replace(/\[0\]/g, `[${newIndex}]`); } // 更新data-circuitNumber属性 if (element.hasAttribute('data-circuitNumber')) { element.setAttribute('data-circuitNumber', newIndex); } // 更新data-EN属性 if (element.hasAttribute('data-EN')) { element.setAttribute('data-EN', newIndex); } // 更新只读的行号输入框的值 if (element.classList.contains('form-control') && element.hasAttribute('readonly')) { element.value = newIndex; } }); // 把克隆行添加到首行的后面(或者表格的tbody里,根据你的结构调整) masterRow.parentNode.appendChild(clonedRow); });
关键细节说明
- 用
cloneNode(true)深度克隆,确保子元素和绑定的事件都被复制 - 用正则表达式
/\[0\]/g全局替换属性里的索引,不管是DB1[0][A]还是其他格式的索引都能精准替换 - 所有ID都要修改避免重复,页面上的ID必须唯一,不然会导致JS选择器出错
- 索引计算基于现有行数,保证每个新行的索引都是连续递增的
这样修改后,你克隆出来的每一行,所有表单元素的name、ID、data-*属性都会跟着行号一起递增,提交表单时后端也能正确识别每一行的数据啦。
内容的提问来源于stack exchange,提问作者JimmyUK1
相关产品推荐
相关产品推荐

