带有数量输入的动态 HTML 表格中的总计计算问题

问题描述 投票:0回答:1

我在动态 HTML 表中遇到总计计算问题,其中可以添加、删除行,并且可以调整数量。添加新行或删除行时会出现此问题;除非手动增加数量,否则总计不会正确更新。

以下是功能的简要概述:

  • 可以将产品从数据列表添加到表中。
  • 每个产品输入的数量可以调整。
  • 可以使用“删除”按钮删除行。

总计预计会随着表格的每次修改而动态更新,但处理计算的 JavaScript 代码似乎存在问题。

// Initial check when the page loads
document.addEventListener("DOMContentLoaded", function() {
  document.getElementById("productTable").style.display = "none";
});

function addProductRow() {
  document.getElementById("productTable").style.display = "table";
  var productInput = document.getElementById("product");
  var productName = productInput.value;

  if (productName.trim() !== "") {
    var productDataList = document.getElementById("products");
    var selectedOption = [...productDataList.options].find(option => option.value === productName);
    updateGrandTotal();

    if (selectedOption) {
      var productPrice = selectedOption.getAttribute("data-price");
      var tableBody = document.getElementById("productTable").getElementsByTagName('tbody')[0];

      var row = tableBody.insertRow();
      row.innerHTML = `
                    <td>${productName}</td>
                    <td>$${productPrice}</td>
                    <td>
                        <input type="number" name="quantity" min="1" value="1" oninput="updateSubtotal(this); updateGrandTotal();">
                    </td>
                    <td class="subtotal">$${productPrice}</td>
                    <td>
                        <button class="remove-button" onclick="removeProductRow(this)">Remove</button>
                    </td>
                `;

      productInput.value = ""; // Clear the product input after adding a row
      updateGrandTotal();
    }
  }
}

function removeProductRow(button) {
  var row = button.parentElement.parentElement;
  row.parentElement.removeChild(row);
  updateGrandTotal();

  //Check if there are no products
  var tableBody = document.getElementById("productTable").getElementsByTagName('tbody')[0];
  if (tableBody.rows.length < 2) {
    document.getElementById("productTable").style.display = "none";
  }

  updateGrandTotal();
}

function updateSubtotal(input) {
  var quantity = parseInt(input.value);
  var unitPriceCell = input.parentElement.previousElementSibling;
  var unitPrice = parseFloat(unitPriceCell.textContent.replace('$', ''));
  var row = input.parentElement.parentElement;

  var subtotalCell = row.querySelector('.subtotal');
  var subtotal = quantity * unitPrice;
  subtotalCell.textContent = `$${subtotal}`;
  updateGrandTotal();
}

function updateGrandTotal() {
  var tableBody = document.getElementById("productTable").getElementsByTagName('tbody')[0];
  var rows = tableBody.getElementsByTagName('tr');
  var grandTotal = 0;

  for (var i = 0; i < rows.length - 1; i++) {
    //console.log("rows length :", rows.length)
    //console.log("i value:", i); // Log the value

    var subtotalCell = rows[i].querySelector('.subtotal');
    //console.log("Sub Total Cell :", rows.length)

    grandTotal += parseInt(subtotalCell.textContent.replace('$', '')) || 0;

    //console.log("grand total :", grandTotal)

    //console.log("")

  }

  var grandTotalRow = document.getElementById("grandTotalRow");
  if (grandTotalRow) {
    grandTotalRow.parentElement.removeChild(grandTotalRow);
  }

  grandTotalRow = tableBody.insertRow();
  grandTotalRow.id = "grandTotalRow";
  grandTotalRow.className = "grand-total-row";
  grandTotalRow.innerHTML = `
            <td colspan="2"></td>
            <td align="right"><strong>Grand Total:</strong></td>
            <td class="subtotal" id="grandTotalValue">$${grandTotal}</td>
            <td></td>
        `;
}
<form>
  <table id="productTable">
    <thead>
      <tr>
        <th>Product Name</th>
        <th>Unit Price</th>
        <th>Quantity</th>
        <th>Sub-Total</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
    </tbody>
  </table>
  <label for="product">Product name:</label>
  <input list="products" name="product" id="product" oninput="addProductRow()">
  <datalist id="products">
    <option value="Product 1" data-price="25">
    <option value="Product 2" data-price="30">
    <option value="Product 3" data-price="15">
    <option value="Product 4" data-price="22">
  </datalist>

  <input type="submit">
</form>

javascript html dom
1个回答
0
投票

更改总计的方式是总计计算的问题。每次运行 updateGrandTotal() 函数时,都会为总计创建一个新行。应改为对当前总计行进行更新。

function updateGrandTotal() {
  var tableBody = document.getElementById("productTable").getElementsByTagName('tbody')[0];
  var rows = tableBody.getElementsByTagName('tr');
  var grandTotal = 0;

  for (var i = 0; i < rows.length - 1; i++) {
    var subtotalCell = rows[i].querySelector('.subtotal');
    grandTotal += parseFloat(subtotalCell.textContent.replace('$', '')) || 0;
  }

  // Find the existing Grand Total row
  var grandTotalRow = document.getElementById("grandTotalRow");

  if (grandTotalRow) {
    // Update the Grand Total value in the existing row
    var grandTotalValueCell = grandTotalRow.querySelector('#grandTotalValue');
    grandTotalValueCell.textContent = `$${grandTotal}`;

    // Remove the row if the Grand Total becomes zero
    if (grandTotal === 0) {
      grandTotalRow.parentElement.removeChild(grandTotalRow);
    }
  } else if (grandTotal > 0) {
    // If Grand Total row doesn't exist, create a new one
    grandTotalRow = tableBody.insertRow();
    grandTotalRow.id = "grandTotalRow";
    grandTotalRow.className = "grand-total-row";
    grandTotalRow.innerHTML = `
      <td colspan="2"></td>
      <td align="right"><strong>Grand Total:</strong></td>
      <td class="subtotal" id="grandTotalValue">$${grandTotal}</td>
      <td></td>
    `;
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.