Tengo una tabla con tres columnas: artículo, precio y una casilla de verificación. Quiero calcular el subtotal pero solo incluyo los precios con una casilla marcada. El código que tengo hasta ahora es una combinación de varios bits que funcionan por sí solos; sin embargo, en este momento recibo el mensaje de error "Error de tipo: no se pueden leer las propiedades de undefined (leyendo 'innerHTML')". ¿Qué estoy haciendo mal?
function calculate() { const ele = document.getElementsByTagName('input'); let table = document.getElementById("myTable"); let tr = table.getElementsByTagName("tr"); let subTotal = 0; for (var i = 0; i < ele.length; i++) { let td = tr[i].getElementsByTagName("td")[1]; let price = td[i].innerHTML; if (ele[i].type == 'checkbox' && ele[i].checked == true) subTotal += price; } document.getElementById("val").innerHTML = "The subtotal is " + subTotal; } <!DOCTYPE html> <html> <body> <table id="myTable"> <tr> <td>T-Shirt</td> <td>9.99</td> <td><input type="checkbox"></td> </tr> <tr> <td>Pants</td> <td>49.99</td> <td><input type="checkbox"></td> </tr> </table> <span id="val">The subtotal is 0</span> <button onclick="calculate()">Calculate subtotal</button> </html>Tienes que cambiar la línea td[i] porque no está definida como sugiere el error. Entonces, considere usar bare td y acceder a su innerText . Devolverá una cadena con el valor, que debe convertir a un número flotante con parseFloat . Finalmente, debe establecer la precisión que desea subTotal para que se imprima con la cantidad de decimales que desea.
function calculate() { const ele = document.getElementsByTagName('input'); let table = document.getElementById("myTable"); let tr = table.getElementsByTagName("tr"); let subTotal = 0; for (var i = 0; i < ele.length; i++) { let td = tr[i].getElementsByTagName("td")[1]; let price = parseFloat(td.innerText); // change here if (ele[i].type == 'checkbox' && ele[i].checked == true) subTotal += price; } document.getElementById("val").innerHTML = "The subtotal is " + subTotal.toFixed(2); // and set precision here } <!DOCTYPE html> <html> <body> <table id="myTable"> <tr> <td>T-Shirt</td> <td>9.99</td> <td><input type="checkbox"></td> </tr> <tr> <td>Pants</td> <td>49.99</td> <td><input type="checkbox"></td> </tr> </table> <span id="val">The subtotal is: </span> <button onclick="calculate()">Calculate subtotal</button> </html>El problema con tu código es simple. Hiciste referencia al td y luego intentas volver a hacer referencia a él.
let td = tr[i].getElementsByTagName("td")[1]; let price = td[i].innerHTML;Debiera ser
const td = tr[i].getElementsByTagName("td")[1]; const price = td.innerHTML;Si usa un valor en la casilla de verificación, puede recorrer las entradas marcadas y calcular el total usando los valores. No es necesario buscar el contenido de las celdas.
function calculate() { const checkedInputs = document.querySelectorAll("#myTable input:checked"); const total = Array.from(checkedInputs).reduce(function(total, cb) { return total + +cb.value; }, 0); document.querySelector("#val").textContent = "The subtotal is " + total.toFixed(2); } <table id="myTable"> <tr> <td>T-Shirt</td> <td>9.99</td> <td><input type="checkbox" value="9.99"></td> </tr> <tr> <td>Pants</td> <td>49.99</td> <td><input type="checkbox" value="49.99"></td> </tr> </table> <span id="val">The subtotal is 0</span> <button onclick="calculate()">Calculate subtotal</button>Puede iterar a través de la casilla de verificación y subir hasta el td anterior
function calculate() { let chckboxes = document.querySelectorAll('#myTable input:checked'); let sum = 0; chckboxes.forEach((itm) => { let val = parseFloat(itm.parentElement.previousElementSibling.innerHTML) sum += val; }); document.getElementById("val").innerHTML = "The subtotal is " + sum; } <!DOCTYPE html> <html> <body> <table id="myTable"> <tr> <td>T-Shirt</td> <td>9.99</td> <td><input type="checkbox"></td> </tr> <tr> <td>Pants</td> <td>49.99</td> <td><input type="checkbox"></td> </tr> </table> <span id="val">The subtotal is 0</span> <button onclick="javascript:calculate()">Calculate subtotal</button> </html>