Order entry form contains product name, price and quantity columns:
<table id="order-products" >
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<td>
Product1
</td>
<td>
<span >0,98</span>
</td>
<td>
<input data-product="4750211645618" 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>
If quantity is changed, order total value should updated. I tried
<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")
for (let i in table.rows) {
const row = table.rows[i]
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)
}
</script>
but got error
Order?Customer=296:12733 Uncaught TypeError: Cannot read properties of undefined (reading '1')
at line
const hind = row.cells[1].childNodes[0].innerHTML
How to properly implement this ? Should pure CSS, javascript or query used?
Modern Chrome browser is used in mobile phone, ASP.NET 6 MVC Razor application.
CodePudding user response:
Your problem is from here
for (let i in table.rows) {}
The value will be "0"
and "length"
(not index like your expectation), so it throws an error while trying to access row.cells["length"].childNodes
(row.cells["length"]
is undefined)
I'd suggest you modify it to
for (const row of table.rows) {}
The full code can be
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" >
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<td>
Product1
</td>
<td>
<span >0,98</span>
</td>
<td>
<input data-product="4750211645618" 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>
CodePudding user response:
As Nick Vu said a first problem is in the for loop and I changed to:
for (let i = 0; i < table.rows.length; i ) {
I find more problems in the code for example the index of the childNodes is wrong, using
console.log(row.cells[1].childNodes)
you can see there are 3 child and you are searching for the middle one (index: 1)
Then for accessing the data of the input element you need to use the .value
property like this:
const kogus = row.cells[2].childNodes[1].value
So I think the final code is:
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
}
const dok = document.getElementById("js-doksumma")
dok.innerText = totalAmount.toFixed(2)
}
<table id="order-products" >
<colgroup>
<col style="width: 80%;">
<col style="width: 10%;">
<col style="width: 10%;">
</colgroup>
<tbody>
<tr>
<td>
Product1
</td>
<td>
<span >0,98</span>
</td>
<td>
<input data-product="4750211645618" 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>
I suggest you to use the console.log()
and log some variable to see if there is somethink wrong with the code.