我在动态 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>
更改总计的方式是总计计算的问题。每次运行 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>
`;
}
}