使用JQuery实现表格每行总价计算异常问题求助
表格行独立计算总价异常问题解决
问题现象
尝试通过数量(quantity)乘以单价(price)计算表格每行的总价时,出现两个问题:
- 计算结果无法正常按格式显示
- 所有行的总价全部显示在同一行,无法实现各行独立计算
原代码
HTML代码
<table class="table"> <thead> <tr> <th>Product Name</th> <th>QTY</th> <th>Box / Pcs</th> <th>Purchase Price </th> <th>Total Cost </th> </tr> </thead> <tbody> {% for v in product %} <tr> <td> <div class="productimgname"> <a href="javascript:void(0);" class="product-img stock-img"> <img src="{{ base_url }}extends/assets/img/products/no_image.jpg" alt="product"> </a> <a href="javascript:void(0);">{{ v.productName }}</a> </div> </td> <td> <div class="product-quantity"> <span class="quantity-btn plus">+<i data-feather="plus-circle" class="plus-circle"></i></span> <input type="text" id="quantity" class="quntity-input qty" name="qtyProduct" value="0"> <input type="hidden" name="idProduct" value="{{ v.productID }}"> <span class="quantity-btn minus"><i data-feather="minus-circle" class="feather-search"></i></span> </div> </td> <td> <span class="pcs_box">0</span> Box / <span class="pcs_total">0</span> pcs </td> <td>MYR. <span id="price" class="amount">{{ v.productPriceSellingMyr }}</span></td> <td>MYR. <span id="total" class="total_amount">0</span> <input type="hidden" class="total_amount_" id="total_idr" name="total_idr" value="0" ></td> </tr> {% endfor %} </tbody> </table>
jQuery代码
$().ready(function(){ $(".minus").click(function(){ changeQuantity(-1,this); calculate(this); }); $(".plus").click(function(){ changeQuantity(this); calculate(this); }); }); function calculate(obj){ var price = parseFloat($(obj).parent().parent().parent().parent().find('.amount').text()) || 0; var quantity = parseInt($(obj).parent().find('.qty').val()); var total = price * quantity; $(obj).parent().parent().parent().find('.total_amount').text(total).toLocaleString('en'); } function changeQuantity(num,obj){ $(obj).parent().find('.qty').val( parseInt($(obj).parent().find('.qty').val())+num); }
问题原因
- 重复ID冲突:循环生成表格行时,使用了重复的
id属性(如quantity、price、total),DOM中ID必须唯一,导致选择器始终匹配第一个元素,所有行的计算结果都渲染到第一行。 - DOM遍历层级冗余且不可靠:通过多层
parent()查找元素,一旦DOM结构变动就会出错,且容易定位到错误的行。 - 参数传递错误:点击加号按钮时,
changeQuantity函数只传递了this,未传递数量增量num,导致数量计算异常。 - 格式化方法调用错误:
toLocaleString应该先对数值调用,再将结果设置为文本,原代码调用顺序错误导致格式化无效。
修复方案
步骤1:修正HTML,移除重复ID
将循环生成元素中的id属性移除,仅保留class(class可以重复使用):
<table class="table"> <thead> <tr> <th>Product Name</th> <th>QTY</th> <th>Box / Pcs</th> <th>Purchase Price </th> <th>Total Cost </th> </tr> </thead> <tbody> {% for v in product %} <tr> <td> <div class="productimgname"> <a href="javascript:void(0);" class="product-img stock-img"> <img src="{{ base_url }}extends/assets/img/products/no_image.jpg" alt="product"> </a> <a href="javascript:void(0);">{{ v.productName }}</a> </div> </td> <td> <div class="product-quantity"> <span class="quantity-btn plus">+<i data-feather="plus-circle" class="plus-circle"></i></span> <input type="text" class="quntity-input qty" name="qtyProduct" value="0"> <input type="hidden" name="idProduct" value="{{ v.productID }}"> <span class="quantity-btn minus"><i data-feather="minus-circle" class="feather-search"></i></span> </div> </td> <td> <span class="pcs_box">0</span> Box / <span class="pcs_total">0</span> pcs </td> <td>MYR. <span class="amount">{{ v.productPriceSellingMyr }}</span></td> <td>MYR. <span class="total_amount">0</span> <input type="hidden" class="total_amount_" name="total_idr" value="0" ></td> </tr> {% endfor %} </tbody> </table>
步骤2:优化jQuery代码,简化遍历并修正逻辑
$(document).ready(function(){ $(".minus").click(function(){ changeQuantity(-1, this); calculate(this); }); $(".plus").click(function(){ changeQuantity(1, this); // 修正参数传递,传入增量1 calculate(this); }); }); function calculate(obj){ // 通过closest找到当前行,再在该行内查找元素,避免多层parent的冗余 const $row = $(obj).closest('tr'); const price = parseFloat($row.find('.amount').text()) || 0; const quantity = parseInt($row.find('.qty').val()) || 0; const total = price * quantity; // 先格式化数值,再设置文本 $row.find('.total_amount').text(total.toLocaleString('en')); // 同步更新隐藏输入框的值 $row.find('.total_amount_').val(total); } function changeQuantity(num, obj){ const $qtyInput = $(obj).parent().find('.qty'); const currentQty = parseInt($qtyInput.val()) || 0; // 确保数量不小于0 const newQty = Math.max(currentQty + num, 0); $qtyInput.val(newQty); }
修复说明
- 用
closest('tr')直接定位当前操作的表格行,DOM结构变动时依然能正确找到目标元素。 - 移除重复ID,避免选择器冲突,确保每行的计算结果渲染到对应行的总价区域。
- 修正
changeQuantity的参数传递,确保加号按钮能正确增加数量,同时限制数量不小于0。 - 调整
toLocaleString的调用顺序,实现数值的千分位格式化。 - 同步更新隐藏输入框的总价,确保表单提交时能获取到正确的每行总价。
内容的提问来源于stack exchange,提问作者Irwan Dwiyanto
相关产品推荐
相关产品推荐

