如果数量更新,如何获得订单总额

How to get order total if quantity is updated

订单输入表单包含产品名称、价格和数量列:

 <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>

如果数量发生变化,订单总价值应该更新。我试过了

<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>

但出现错误

如何正确实施?应该使用纯 CSS、javascript 还是查询?

现代 Chrome 浏览器用于移动 phone、ASP.NET 6 MVC Razor 应用程序。

你的问题出在这里

for (let i in table.rows) {}

该值将是 "0""length"(不是您期望的索引),因此在尝试访问 row.cells[0].childNodes 时抛出错误(row.cells 未定义)

我建议你修改为

for (const row of table.rows) {}

完整代码可以

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 Vu 所说,第一个问题是在 for 循环中,我改为:

for (let i = 0; i < table.rows.length; i++) {

我在代码中发现了更多问题,例如 child 节点的索引是错误的,使用

console.log(row.cells[1].childNodes)

您可以看到有 3 个 child,您正在搜索中间的那个(索引:1)

然后为了访问输入元素的数据,您需要像这样使用 .value 属性:

const kogus = row.cells[2].childNodes[1].value

********************* 编辑 *******************

随着答案的改变更改代码。

要访问 html 元素的数据,请使用 .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>

我建议你使用 console.log() 并记录一些变量,看看代码是否有问题。

尼克是对的。请记住 table.rows 不是数组而是 HTMLCollection。您只需执行以下操作即可解决此问题:

  const table = document.getElementById("order-products")
  for (const row of Array.from(table.rows)) {
  }

如果您想亲眼看看有一个“长度”属性 被迭代,请打开开发工具,select 元素选项卡中的 table,然后运行 控制台中的这段代码:

for (let i in [=11=].rows) {
    console.log(i);
    console.log([=11=].rows[i].cells[0]);
}

您将看到最后一次迭代打印“长度”,然后抛出异常。