Laravel循环中jQuery动态计算总价异常问题排查
jQuery实现商品总价计算时全行同步更新的BUG
在CRUD系统中使用jQuery实现功能:输入商品数量后,与数据库存储的单价相乘,结果显示在当前行的总价字段中。但目前所有行的总价字段都会被同步更新,尝试多种方法仍未解决。
视图文件(Laravel Blade)
<?php $i=1; ?> @foreach ($productData as $rsproductData) <tr> <td><?php echo $i ?></td> <?php $i++; ?> <td class="d-none">{{$rsproductData->id}}</td> <td>{{$rsproductData->products}}</td> <td>{{$rsproductData->wholesale}}</td> <!-- 新增类名,后续精准获取单价 --> <td class="unit-price">{{$rsproductData->price}}</td> <td><input type="number" class="form-control qtyChckInput mb-2" name="qty"></td> <td class="totalPrice" name="totalPrice">0</td> <td><button class="btn btn-success editModalBtn">Edit</button></td> <td><button class="btn btn-danger deleteModalBtn">Delete</button></td> </tr> @endforeach <tfoot> <tr> <td></td><td></td><td></td><td></td> <th>Item Total</th> <td id="itemTotal">0</td> <td></td><td></td> </tr> <tr> <td></td><td></td><td></td><td></td> <th>10% discount on Item Total</th> <td id="itemDiscount">0</td> <td></td><td></td> </tr> <tr> <td></td><td></td><td></td><td></td> <th>5% Tax on Item Total</th> <td id="itemTax">0</td> <td></td><td></td> </tr> <tr> <td></td><td></td><td></td><td></td> <th>Grand Total</th> <td id="itemGrand">0</td> <td></td><td></td> </tr> </tfoot> </tbody>
原JS代码
$('input[name*="qty"]').keyup(function() { $tr = $(this).closest('tr'); var data = $tr.children("td").map(function () { return $(this).text(); }).get(); text = $(this).val(); $(".totalPrice").html(data[4] * text) var itemTotal = $('.totalPrice').html(); $('#itemTotal').html(itemTotal); var itemDiscount = itemTotal * (1 - 10 / 100); $('#itemDiscount').html(itemTotal - itemDiscount); var itemTax = itemTotal * (1 - 5 / 100); $('#itemTax').html(itemTotal - itemTax); var itemGrand = itemTax + itemDiscount - itemTotal; console.log(itemGrand); $('#itemGrand').html(itemGrand); });
问题分析与修复
核心问题
- 全局选择器
$(".totalPrice")会选中所有行的总价元素,导致全行同步更新 - 合计计算仅取第一个
totalPrice的内容,未遍历所有行求和 - 折扣、税费的计算公式逻辑错误
修复后的JS代码
$('input[name*="qty"]').keyup(function() { const $tr = $(this).closest('tr'); // 精准获取当前行的单价,避免依赖硬编码索引 const unitPrice = parseFloat($tr.find('.unit-price').text()) || 0; const qty = parseFloat($(this).val()) || 0; const rowTotal = unitPrice * qty; // 仅更新当前行的总价 $tr.find('.totalPrice').html(rowTotal.toFixed(2)); // 遍历所有行计算总价之和 let itemTotal = 0; $('.totalPrice').each(function() { itemTotal += parseFloat($(this).text()) || 0; }); $('#itemTotal').html(itemTotal.toFixed(2)); // 修正折扣计算:10%折扣即总价的10% const itemDiscount = itemTotal * 0.1; $('#itemDiscount').html(itemDiscount.toFixed(2)); // 修正税费计算:5%税费即总价的5% const itemTax = itemTotal * 0.05; $('#itemTax').html(itemTax.toFixed(2)); // 修正总计计算:总价 - 折扣 + 税费 const itemGrand = itemTotal - itemDiscount + itemTax; $('#itemGrand').html(itemGrand.toFixed(2)); });
额外优化点
- 给单价
<td>添加unit-price类,避免依赖data[4]硬编码索引,后续HTML结构变动时不易出错 - 使用
parseFloat()处理数值,用|| 0处理空值/非数值情况,避免计算错误 - 用
toFixed(2)保留两位小数,符合金额显示规范
内容的提问来源于stack exchange,提问作者zoomauto
相关产品推荐
相关产品推荐

