You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript动态表格余额计算功能异常排查求助

JavaScript动态表格余额计算功能异常排查求助

大家好,我现在遇到了一个JavaScript的问题,需要根据输入框的值计算并更新表格里的余额。我已经梳理了需求,写了相关代码,但计算功能始终没法正常工作,想请大家帮忙看看问题出在哪。

具体问题说明

我有一个ID为#toggle_table的表格,用来展示支付历史,每一行代表一笔支付记录。每行里有一个输入框(td.editable-amount-paid input),用户可以在这里输入支付金额;同一行还有一个余额单元格(td.balance-cell),需要根据总计金额和累计已支付金额动态更新。

功能需求

  • 总计金额从$('#customer_gtotal').val()获取
  • 每行的余额单元格需要显示总计金额减去截至当前行的累计已支付金额的差值
  • 用户编辑某行的支付金额输入框时,该行及后续行的余额单元格都要相应更新
  • 余额要在用户输入时实时更新

当前实现代码及问题

我尝试用下面的代码实现,但效果不符合预期:当修改某行输入框的金额时,该行和后续行的余额没有正确更新。

function updateBalances() {
  var cumulativePayment = 0;

  // 遍历表格行
  $('#toggle_table tbody tr').each(function() {
    try {
      var inputField = $(this).find('.editable-amount-paid input');
      var balanceCell = $(this).find('.balance-cell');

      // 获取当前行的支付金额
      var paymentAmount = parseFloat(inputField.val()) || 0;

      // 累计支付金额
      cumulativePayment += paymentAmount;

      // 更新当前行的余额单元格
      balanceCell.text(cumulativePayment.toFixed(2));
    } catch (error) {
      // 记录行更新时的错误
      console.error('Error updating row:', error);
    }
  });
}

$('#toggle_table tbody tr .editable-amount-paid input').on('input', updateBalances);

updateBalances();

预期效果示例

假设总计金额是3500:

  • 当把第一行输入框的值改为3000时,第一行余额应该是3500 - 3000 = 500
  • 第二行如果原有支付金额是1000,那么第二行余额应该是500 - 1000 = -500
    但实际代码并没有实现这个逻辑。

补充:表格是动态生成的

表格是通过AJAX请求后动态创建的,相关代码如下:

$('#payment_history').click(function(event) {
  $('#current_in_id').val($('#invoice').val());
  var dataString = {
    dataString: $("#histroy").serialize()
  };
  dataString[csrfName] = csrfHash;

  $.ajax({
    type: "POST",
    dataType: "json",
    url: "<?php echo base_url(); ?>Cinvoice/payment_history",
    data: $("#histroy").serialize(),
    success: function(data) {
      var basedOnCustomer = data.based_on_customer;
      var overallGTotal = parseFloat(data.overall[0].overall_gtotal);
      var overall_due = parseFloat(data.overall[0].overall_due);
      var overall_paid = parseFloat(data.overall[0].overall_paid);
      console.log("OVER : " + overallGTotal);

      var gt = $('#customer_gtotal').val();
      var amtpd = data.amt_paid;
      var bal = $('#customer_gtotal').val() - data.amt_paid;

      var total = "<table id='table2' class='newtable table table-striped table-bordered'><tbody><tr><td rowspan='2' style='vertical-align: middle;text-align-last: center;'><b>Grand Total :  <?php  echo $currency;  ?>" + $('#customer_gtotal').val() + "<b></td><td class='td' style='border-right: hidden;'><b>Total Amount Paid :<b></td><td><?php  echo $currency;  ?><span class='amt_paid_update'><input type='text' value='" + data.amt_paid + "' name='tl_amt_pd'/></span></td><td><input type='hidden' value='" + $('#customer_gtotal').val() + "' name='t_unique'/><span style='font-weight:bold;'>INVOICE NO</span> :<input type='hidden' value='" + $('#invoice').val() + "' name='unq_inv'/>" + $('#invoice').val() + "</td></tr><tr><td class='td' ><b>Balance :<input type='text' value='" + bal + "' name='my_bal_1'/><b></td><td class='due_pay' style='display:none;' id='balance-cell' data-currency='<?php  echo $currency;  ?>'>" + bal + "</td><td  data-currency='<?php echo $currency; ?>'><span style='font-weight:bold;'>Amount to Pay : </span><input type='text' id='amount_pay_unique' class='amount_pay' style='text-align:center;' name='amount_pay_1'/></td><td style='display:none'><input type='text'  value='<?php if($all_invoice[0]['payment_id']){ echo $all_invoice[0]['payment_id']; }else{ echo $payment_id_new;}?>' name='payment_id_this_invoice' class='payment_id_val' id='payment_id'/></td><td style='display:none' class='' data-currency='<?php echo $currency; ?>'><input type='text' name='updated_bal_uniq' class='balance-col'/></td><td> <input type='text' id='total-amount' placeholder='Enter Amount To Distribute'></td></tr></tbody></table>"

      var table_header = "<div class='toggle-button' onclick='toggleTable()'>Payment History &#9660;</div><table id='toggle_table' class='table table-striped table-bordered'><thead style='FONT-WEIGHT:BOLD;'><tr><td>S.NO</td><td>Payment Date</td><td>Reference.NO</td><td>Bank Name</td><td>Amount Paid</td><td>Balance</td><td>Details</td><td>Action</td></tr></thead><tbody>";

      var table_footer = "</tbody></table>";
      var html = "";
      var count = 1;

      data.payment_get.forEach(function(element) {
        html += "<tr><td>" + count + "</td><td>" + element.payment_date + "</td><td>" + element.reference_no + "</td><td>" + element.bank_name + "</td><td  class='editable-amount-paid' data-currency='<?php echo $currency; ?>'>" + element.amt_paid + "</td><td class='balance-cell' contenteditable='false'>" + element.balance + "</td><td>" + element.details + "</td><td style='display:none;'><input type='hidden'  class='payment_id_val' id='payment_id'/></td><td><button style='color:white;background-color: #38469f;padding:2px;font-weight:bold;' onclick='editRow(this)'>Edit</button> </td></tr>";
        count++;
      });

      var all = total + table_header + html + table_footer;

      var total1 = "<table id='table1'  class='table table-striped table-bordered'><tr><td colspan='3' style='border-top: hidden!important;background-color: white;text-align:center;font-weight:bold;font-size:18px;'>LIST OF DUE INVOICES</td></tr><tr><td rowspan='2' style='vertical-align: middle;text-align-last: center;'><b>Grand Total :  <?php  echo $currency;  ?>" + overallGTotal.toFixed(2) + "<b></td><td class='td' style='border-right: hidden;'><b>Total Amount Paid :<b></td><td><?php  echo $currency;  ?>" + overall_paid.toFixed(2) + "</td></tr></tr><td class='td' style='border-right: hidden;'><b>Balance :<b></td><td id='balance-cell' data-currency='<?php echo $currency;  ?>'>" + parseFloat(overall_due.toFixed(2)) + "</td></tr></table>"

      var table_header1 = "<table class='newtable-second table table-striped table-bordered'><thead style='FONT-WEIGHT:BOLD;'><tr><td style='width:10px;'>S.NO</td><td><div id='distribute-container'> </div></td><td style='width:60px;'>Invoice No</td><td style='width:100px;'>Total Amount</td><td style='width:200px;'>Amount Paid</td><td style='width:200px;'>Balance</td><td style='width:200px;'>Amount to Pay</td><td class='balance-column' style='width:200px;'>Updated Balance</td></tr></thead><tbody>";
      var table_footer1 = "</tbody><tfoot><tr><td colspan='6'></td><td class='t_amt_pay'></td><td style='display:none;' class='balance-col t_bal_pay'></td></tr></tfoot></table>";
      var html1 = "";
      var count1 = 1;

      for (var invoiceId in basedOnCustomer) {
        if (basedOnCustomer.hasOwnProperty(invoiceId)) {
          var element = basedOnCustomer[invoiceId];
          var pay_id = element.payment_id;
          console.log("PAY :" + pay_id);
          var random10DigitNumber = '';
          if (pay_id == '' || pay_id == '0') {
            random10DigitNumber = generateRandom10DigitNumber();
          } else {
            random10DigitNumber = pay_id;
          }
          html1 += "<tr><td style='display:none;'><input type='hidden' value='" + random10DigitNumber + "' name='payment_id[]'/></td><td>" + count1 + "</td><td> <input type='checkbox' id='<?php echo $count1; ?>' class='checkbox-distribute'></td><td><input type='text' readonly style='text-align:center;'  value='" + element.commercial_invoice_number + "' name='invoice_no[]'/></td><td><input type='text' readonly class='g_pament' value='" + element.gtotal + "' name='total_amt[]' style='text-align:center;'/></td><td>" + element.paid_amount + "</td><td class='due_pay' data-currency='<?php echo $currency; ?>'>" + element.due_amount + "</td><td  data-currency='<?php echo $currency; ?>'><input type='text' id='amount_pay' class='amount_pay' style='text-align:center;' name='amount_pay[]'/></td><td class='balance-column' data-currency='<?php echo $currency; ?>'><input type='text' name='updated_bal[]' readonly class='balance-col'/></td></tr>";
          count1++;
        }
      }

      all += total1 + table_header1 + html1 + table_footer1;

      var table_header2 = "<div id='pay_now_table'><table class='table table-striped table-bordered'><tr><th>Date</th><th>Bank</th><th>Reference No</th><th>Payment Amount</th><th>Action</th></tr><tr><td><input type='date' name='bulk_payment_date' value='<?php echo html_escape($date); ?>'/></td><td><select name='bulk_bank' id='bank'  class='form-control bankpayment' > <option value='JPMorgan Chase'>JPMorgan Chase</option> <option value='SoFi'>SoFi</option> <?php foreach($bank_list as $b){ ?> <option value='<?=$b['bank_name']; ?>'><?=$b['bank_name']; ?></option> <?php } ?> </select></td><td><input type='text' name='bulk_pay_ref' placeholder='Ref No'/></td><td class='t_amt_pay'></td>";
      var table_footer2 = "<td><input type='submit' style='color:white;background-color: #38469f;padding:2px;font-weight:bold;' id='pay_now' value='PAY NOW'/></td></tr></tbody></table></div>";

      all += table_header2 + table_footer2;

      $('#salle_list').html(all);
      $('#payment_history_modal').modal('show');
      $('#pay_now_table').hide();
      $('.balance-column').hide();

      var amountPaidCells = document.querySelectorAll('#salle_list tbody tr td:nth-child(5)'); // Assuming "Amount Paid" is the 5th column
      amountPaidCells.forEach(function(cell) {
        cell.addEventListener('input', function() {
          updateBalances();
        });
      });
    }
  });
  event.preventDefault();
});

表格渲染后的示例结构

<table id="toggle_table" class="table table-striped table-bordered" style="display: table;">
<thead style="FONT-WEIGHT:BOLD;">
<tr>
<td>S.NO</td>
<td>Payment Date</td>
<td>Reference.NO</td>
<td>Bank Name</td>
<td>Amount Paid</td>
<td>Balance</td>
<td>Details</td>
<td>Action</td>
</tr>
</thead>
<tbody>
<tr data-row-id="unique_row_id_1696080502903">
<td>1</td>
<td><input type="text" class="editable-input-1" name="inputField1"></td>
<td><input type="text" class="editable-input-2" name="inputField2"></td>
<td><input type="text" class="editable-input-3" name="inputField3"></td>
<td class="editable-amount-paid" data-currency="$"><input type="text" class="editable-input-4" name="inputField4"></td>
<td class="balance-cell" contenteditable="false">500.00</td>
<td><input type="text" class="editable-input-6" name="inputField6"></td>
<td style="display:none;"><input type="text" class="editable-input-7" name="inputField7"></td>
<td><button class="save-button" style="background-color: rgb(56, 70, 159); color: white; font-weight: bold;">Update</button></td>
</tr>
<tr>
<td>2</td>
<td>2021-11-15</td>
<td>0</td>
<td>JPMorgan Chase</td>
<td class="editable-amount-paid" data-currency="$">3077.35</td>
<td class="balance-cell" contenteditable="false">500.00</td>
<td>2</td>
<td style="display:none;"><input type="hidden" class="payment_id_val" id="payment_id"></td>
<td><button style="color:white;background-color: #38469f;padding:2px;font-weight:bold;" onclick="editRow(this)">Edit</button> </td>
</tr>
</tbody>
</table>

希望有大佬能帮我检查代码,找出余额计算的问题所在,给我一些修改建议让功能正常工作,谢谢!


备注:内容来源于stack exchange,提问作者Surya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 12:04:28