如何从动态表格读取数据到数组并在新增行时验证数据
动态表格数据存储与新增验证问题修复
我刚开始学习JavaScript编程,实现了带增删行功能的动态表格,但遇到两个问题:
- 存储表格数据到数组时,只能保存第一行的数据,无法遍历所有行
- 需要在新增行时完成数据验证
HTML代码
<table id="mytableform1" width="100%" border="1" cellspacing="0" cellpadding="0" style="border: 1px solid;color: #5c6873;background-color: #fff;border-color: #e4e7ea;"> <tr> <td rowspan="2" align="center" valign="top">Vértices da poligonal</td> <td colspan="3" align="center" valign="top">Coordenadas no sistema PT - TM06/ETRS89</td> </tr> <tr> <td align="center" valign="top">M(m)</td> <td align="center" valign="top">P(m)</td> </tr> <tr id="allDataRow"> <td align="center" valign="top"> <input style="width: 100%;" class="form-control" type="number" name="namesavedata1[]" id="val_1" placeholder="1"> </td> <td align="center" valign="top"> <input style="width: 100%;" class="form-control" type="number" name="namesavedata2[]" id="val_2" placeholder="00000,000"> </td> <td align="center" valign="top"> <input style="width: 100%;" class="form-control" type="number" name="namesavedata3[]" id="val_3" placeholder="00000,000"> </td> </tr> </table> <div style="display:flex;justify-content: space-between;"> <div style="display:flex;"> <button onclick="addRow()" style="background-color: #673ab7c7;color: white;" class="btn" type="button"> <span class="bi bi-plus-square-dotted"></span>+ </button> <button onclick="deleteRow()" style="background-color: #673ab7c7;color: white;" class="btn" type="button"> <span class="bi bi-plus-square-dotted"></span>- </button> </div> <div style="display:flex;"> <button type="button" name="button" onclick="arraySaveData()" class="btn" style="background-color: #673ab7c7;color: white;"> Validar </button> </div> </div>
原JavaScript代码
function arraySaveData() { var data = []; $('#mytableform1').each(function () { data.push({ verticePolig: $('input[name="namesavedata1[]"]').val(), }); data.push({ coordM: $('input[name="namesavedata2[]"]').val(), }); data.push({ coordP: $('input[name="namesavedata3[]"]').val(), }); }); console.log(data); } //Button add table row function addRow() { var table = document.getElementById("mytableform1"); var rowCount = table.rows.length; x = document.getElementById("mytableform1").rows.length; var row = table.insertRow(); var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); var cell3 = row.insertCell(2); //numeração crescente for (var i = 0; i < x; i++) { cell1.innerHTML = '<input type="text" class="form-control" name="namesavedata1[]" align="center" placeholder="' + (cell1.innerHTML = i + 0) + '">'; cell2.innerHTML = '<input type="text" class="form-control" name="namesavedata2[]" align="center" placeholder="00000,000">'; cell3.innerHTML = '<input type="text" class="form-control" name="namesavedata3[]" align="center" placeholder="00000,000">'; } } //Button delete table row function deleteRow() { var table = document.getElementById("mytableform1"); var rowCount = table.rows.length; if (rowCount >= 4) { table.deleteRow(rowCount - 1); } else { Swal.fire({ title: 'Erro!', text: "Não pode apagar este campo", icon: 'warning', showCancelButton: true, confirmButtonColor: '#e55353', cancelButtonColor: '#636f83', confirmButtonText: 'ok' }) } }
问题分析与修复方案
1. 数据存储异常修复
原代码仅遍历表格容器,且通过name选择器取输入框值时只会返回第一个匹配项。正确逻辑是遍历所有数据行(跳过前两行表头),每行收集三个输入框的值组成一个对象存入数组。
2. 新增行函数优化
原addRow中的for循环完全错误,会重复覆盖单元格内容。修正后直接根据当前行号生成顶点编号,同时保留输入框的number类型,确保输入合法性。
3. 数据验证实现
新增验证函数,在保存时检查所有行的数据是否为空、是否为有效数字,删除行后自动重新编号顶点,避免编号混乱。
修改后的完整JavaScript代码
// 验证所有行数据 function validateRows() { let isValid = true; const rows = document.querySelectorAll('#mytableform1 tr:not(:nth-child(1)):not(:nth-child(2))'); rows.forEach((row, index) => { const inputs = row.querySelectorAll('input'); const vertice = inputs[0].value.trim(); const coordM = inputs[1].value.trim(); const coordP = inputs[2].value.trim(); // 验证必填项 if (!vertice || !coordM || !coordP) { Swal.fire({ title: 'Erro!', text: `Linha ${index + 1}: Todos os campos são obrigatórios`, icon: 'error', confirmButtonColor: '#e55353', confirmButtonText: 'ok' }); isValid = false; return; } // 验证数字格式(支持逗号作为小数点分隔符) const numRegex = /^\d+(,\d{1,3})?$/; if (!numRegex.test(coordM) || !numRegex.test(coordP)) { Swal.fire({ title: 'Erro!', text: `Linha ${index + 1}: Coordenadas devem ser números no formato 00000,000`, icon: 'error', confirmButtonColor: '#e55353', confirmButtonText: 'ok' }); isValid = false; return; } }); return isValid; } // 保存数据到数组 function arraySaveData() { if (!validateRows()) return; const data = []; // 遍历所有数据行(跳过前两行表头) $('#mytableform1 tr').slice(2).each(function () { const $row = $(this); data.push({ verticePolig: $row.find('input[name="namesavedata1[]"]').val(), coordM: $row.find('input[name="namesavedata2[]"]').val(), coordP: $row.find('input[name="namesavedata3[]"]').val() }); }); console.log('Dados salvos:', data); // 这里可以添加提交数据的逻辑 } // 新增表格行 function addRow() { const table = document.getElementById("mytableform1"); const rowCount = table.rows.length; // 新行的顶点编号为当前数据行数量+1(前两行是表头) const verticeNum = rowCount - 1; const row = table.insertRow(); const cell1 = row.insertCell(0); const cell2 = row.insertCell(1); const cell3 = row.insertCell(2); // 生成输入框,保留number类型,设置正确的编号 cell1.innerHTML = `<input type="number" class="form-control" name="namesavedata1[]" align="center" value="${verticeNum}" readonly>`; cell2.innerHTML = '<input type="number" step="0.001" class="form-control" name="namesavedata2[]" align="center" placeholder="00000,000">'; cell3.innerHTML = '<input type="number" step="0.001" class="form-control" name="namesavedata3[]" align="center" placeholder="00000,000">'; } // 删除表格行 function deleteRow() { const table = document.getElementById("mytableform1"); const rowCount = table.rows.length; if (rowCount >= 4) { table.deleteRow(rowCount - 1); // 删除后重新编号所有数据行的顶点 const rows = table.querySelectorAll('tr:not(:nth-child(1)):not(:nth-child(2))'); rows.forEach((row, index) => { row.querySelector('input[name="namesavedata1[]"]').value = index + 1; }); } else { Swal.fire({ title: 'Erro!', text: "Não pode apagar este campo", icon: 'warning', showCancelButton: true, confirmButtonColor: '#e55353', cancelButtonColor: '#636f83', confirmButtonText: 'ok' }) } }
内容的提问来源于stack exchange,提问作者Ana Gomes
相关产品推荐
相关产品推荐

