El formulario de entrada de pedidos contiene columnas de nombre de producto, precio y cantidad:
<table id="order-products" class="mobileorder-table"> <colgroup> <col style="width: 80%;"> <col style="width: 10%;"> <col style="width: 10%;"> </colgroup> <tbody> <tr> <td> Product1 </td> <td> <span class="mobileorder-price">0,98</span> </td> <td> <input data-product="4750211645618" class="quantity" id="product_Soodkogus" name="product.Soodkogus" type="number" min="0" max="999999" value="" onblur="orderSumRefresh()" /> </td> </tr> </tbody> </table> Order total <p id="js-doksumma"></p>Si se cambia la cantidad, el valor total del pedido debe actualizarse. Lo intenté
<script> function parseFloatFormatted(txt) { if (typeof txt !== 'string' || txt === null || txt === "") { return 0 } return parseFloat(txt.replace(',', '.').replace(' ', '')) } function orderSumRefresh() { let totalAmount = 0 const table = document.getElementById("order-products") table.rows.forEach((row) => { //for (let i in table.rows) { // const row = table.rows[i] const hind = row.cells[1].querySelector(".mobileorder-price").value const kogus = row.cells[2].querySelector(".quantity").value const rowSum = Math.round(parseFloatFormatted(hind)* parseFloatFormatted(kogus) * 100) / 100 totalAmount += rowSum }); var dok = document.getElementById("js-doksumma") dok.innerText = totalAmount.toFixed(2) } </script>pero obtuve un error
¿Cómo implementar correctamente esto? ¿Se debe usar CSS puro, javascript o consulta?
El navegador Chrome moderno se utiliza en el teléfono móvil, la aplicación ASP.NET 6 MVC Razor.
Como dijo Nick Vu, un primer problema está en el ciclo for y cambié a:
for (let i = 0; i < table.rows.length; i++) {Encuentro más problemas en el código, por ejemplo, el índice de childNodes está mal, usando
console.log(row.cells[1].childNodes)puede ver que hay 3 niños y está buscando el del medio (índice: 1)
Luego, para acceder a los datos del elemento de entrada, debe usar la propiedad .value de esta manera:
const kogus = row.cells[2].childNodes[1].value********************* EDITAR *******************
Cambiando el código ya que la respuesta ha cambiado.
Para acceder a los datos del elemento html, use la propiedad .innerHTML .
function parseFloatFormatted(txt) { if (typeof txt !== 'string' || txt === null || txt === "") { return 0 } return parseFloat(txt.replace(',', '.').replace(' ', '')) } function orderSumRefresh() { let totalAmount = 0 const table = document.getElementById("order-products") /* for (let i = 0; i < table.rows.length; i++) { const row = table.rows[i] const hind = row.cells[1].childNodes[1].innerHTML const kogus = row.cells[2].childNodes[1].value const rowSum = Math.round(parseFloatFormatted(hind) * parseFloatFormatted(kogus) * 100) / 100 totalAmount += rowSum } */ for (const row of table.rows) { const hind = row.cells[1].querySelector(".mobileorder-price").innerHTML const kogus = row.cells[2].querySelector(".quantity").value const rowSum = Math.round(parseFloatFormatted(hind)* parseFloatFormatted(kogus) * 100) / 100 totalAmount += rowSum } const dok = document.getElementById("js-doksumma") dok.innerText = totalAmount.toFixed(2) } <table id="order-products" class="mobileorder-table"> <colgroup> <col style="width: 80%;"> <col style="width: 10%;"> <col style="width: 10%;"> </colgroup> <tbody> <tr> <td> Product1 </td> <td> <span class="mobileorder-price">0,98</span> </td> <td> <input data-product="4750211645618" class="quantity" id="product_Soodkogus" name="product.Soodkogus" type="number" min="0" max="999999" value="" onblur="orderSumRefresh()" /> </td> </tr> </tbody> </table> Order total <p id="js-doksumma"></p> Le sugiero que use console.log() y registre alguna variable para ver si hay algún problema con el código.
tu problema es de aqui
for (let i in table.rows) {} El valor será "0" y "length" (no índice como su expectativa), por lo que arroja un error al intentar acceder a row.cells[0].childNodes ( row.cells no está definido)
Te sugiero que lo modifiques para
for (const row of table.rows) {}El código completo puede ser
function parseFloatFormatted(txt) { if (typeof txt !== 'string' || txt === null || txt === "") { return 0 } return parseFloat(txt.replace(',', '.').replace(' ', '')) } function orderSumRefresh() { let totalAmount = 0 const table = document.getElementById("order-products") for (const row of table.rows) { const hind = row.cells[1].childNodes[0].innerHTML const kogus = row.cells[2].childNodes[0].innerText const rowSum = Math.round(parseFloatFormatted(hind) * parseFloatFormatted(kogus) * 100) / 100 totalAmount += rowSum } const dok = document.getElementById("js-doksumma") dok.innerText = totalAmount.toFixed(2) } <table id="order-products" class="mobileorder-table"> <colgroup> <col style="width: 80%;"> <col style="width: 10%;"> <col style="width: 10%;"> </colgroup> <tbody> <tr> <td> Product1 </td> <td> <span class="mobileorder-price">0,98</span> </td> <td> <input data-product="4750211645618" class="quantity" id="product_Soodkogus" name="product.Soodkogus" type="number" min="0" max="999999" value="" onblur="orderSumRefresh()" /> </td> </tr> </tbody> </table> Order total <p id="js-doksumma"></p>Nick tiene razón. Recuerde que table.rows no es una matriz sino una HTMLCollection. Puede solucionar el problema simplemente haciendo:
const table = document.getElementById("order-products") for (const row of Array.from(table.rows)) { }Si desea ver por sí mismo que se está iterando una propiedad de "longitud", abra las herramientas de desarrollo, seleccione la tabla de la pestaña de elementos y ejecute este fragmento en la consola:
for (let i in $0.rows) { console.log(i); console.log($0.rows[i].cells[0]); }Verá la última iteración imprimir "longitud" y luego lanzar una excepción.