基于Jquery实现动态生成字段的数量×金额行内实时计算问题
解决动态生成字段的行内实时计算问题
我看了你的代码,问题出在你获取qty和amount值的方式上——$(".qty").val()只会返回第一个匹配元素的值,所以动态新增的行输入时,永远只会用第一行的数值计算,自然得不到正确的行内结果。
下面是修复后的完整代码,我还帮你完善了每行小计和整体总计的逻辑:
修复后的HTML
<div class="form-group"> <form name="add_name" id="add_name"> <div class="table-responsive"> <table class="table table-bordered" id="dynamic_field"> <tr> <td><input type="text" name="qty[]" placeholder="Enter your Qty" class="form-control qty" /></td> <td><input type="text" name="amount[]" placeholder="Enter your amount" class="form-control amount" /></td> <td><input type="text" name="total[]" class="form-control total" readonly /></td> <td><button type="button" name="add" id="add" class="btn btn-success">Add More</button></td> </tr> </table> <input type="button" name="submit" id="submit" class="btn btn-info" value="Submit" /> </div> <div>Total: <label id='grand_total'>0</label></div> </form> </div>
修复后的JS
$(document).ready(function(){ var i=1; // 添加新行 $('#add').click(function(){ i++; $('#dynamic_field').append(` <tr id="row${i}"> <td><input type="text" name="qty[]" placeholder="Enter your qty" class="form-control qty" /></td> <td><input type="text" name="amount[]" placeholder="Enter your amount" class="form-control amount" /></td> <td><input type="text" name="total[]" class="form-control total" readonly /></td> <td><button type="button" name="remove" id="${i}" class="btn btn-danger btn_remove">X</button></td> </tr> `); }); // 移除行 $(document).on('click', '.btn_remove', function(){ var button_id = $(this).attr("id"); $('#row'+button_id).remove(); calculateGrandTotal(); // 移除后重新计算总合计 }); // 行内计算:Qty × Amount = 该行Total $(document).on('keyup', '.qty, .amount', function(){ // 获取当前输入框所在的行 var $row = $(this).closest('tr'); // 取当前行的qty和amount值,空值默认为0 var qty = parseFloat($row.find('.qty').val()) || 0; var amount = parseFloat($row.find('.amount').val()) || 0; // 计算该行小计并赋值 var rowTotal = qty * amount; $row.find('.total').val(rowTotal.toFixed(2)); // 保留两位小数更规范 // 计算整体总合计 calculateGrandTotal(); }); // 计算所有行的总合计 function calculateGrandTotal(){ var grandTotal = 0; $(".total").each(function(){ grandTotal += parseFloat($(this).val()) || 0; }); $("#grand_total").text(grandTotal.toFixed(2)); } // 提交表单 $('#submit').click(function(){ $.ajax({ url:"name.php", method:"POST", data:$('#add_name').serialize(), success:function(data) { alert(data); $('#add_name')[0].reset(); $("#grand_total").text('0'); // 重置总合计 } }); }); });
关键改动说明
- 每行添加小计字段:在表格中新增了只读的
total输入框,用来显示每行的计算结果,同时表单提交时也能把小计值一并传回后端。 - 基于当前行取值:用
$(this).closest('tr')定位到当前输入框所在的行,再通过$row.find()获取当前行的qty和amount值,彻底避免了取到第一行旧值的问题。 - 空值与异常处理:用
parseFloat(val) || 0处理空输入或非数字的情况,防止计算出现NaN错误。 - 总合计自动同步:不管是输入数值还是移除行,都会自动调用
calculateGrandTotal()重新计算所有行的小计总和,实时更新页面上的总合计。 - 代码复用优化:把总合计的计算逻辑抽成独立函数,避免重复编写相同代码,提升可读性和维护性。
这样修改后,不管是初始的第一行还是动态新增的行,都能正确计算每行的Quantity × Amount,并且整体总合计也会实时同步更新。
内容的提问来源于stack exchange,提问作者Jasshh Andrews
相关产品推荐
相关产品推荐

