【问题标题】:How to calculate html table column datahtml表格列数据如何计算
【发布时间】:2019-07-22 20:01:28
【问题描述】:

我有一个动态创建的 HTML 表,当页面加载时,我正在创建具有以下列的第一行 ItemName,I Code,MRP,Price,UnitQty,Disc%,DiscAmt ,Gst%,GstAmtTotalAmt

ItemName 是自动完成字段,因此用户通过键入来选择项目名称,当用户关注时我正在填充一些相应的字段,当用户在 UnitQty 字段内键入时,我正在计算一些值并根据相应的值进行填充keyup 事件上的字段所有这些都发生在 HTML 表中

在表格之外我有一个输入字段SubTotal,这是我通过一些计算得到的,即price * UnitQty,因此对于相应的表格行有一个总Amt列,我必须填充(price * UnitQty) +GstAmt +DiscAmt,但目前我正在填充price * UnitQty我稍后会这样做

我的问题是什么

所以下面是一个subTotal 输入字段,我在其中填充每一行的price * UnitQty,所以我将值存储在全局变量中,然后将当前变量添加到其中,但是当我输入假设 2 并且价格为 100 时等于 200 然后我删除 2 并写入 2 那时它正在添加前一个 200 和当前 300 并填充 500 我知道这是因为 keyup 它也在添加以前的值,但这是不正确的

HTML 表格中没有小计列,这就是我将其存储在变量中的原因

function format(number, decimals = 2) {
  const fixed = parseFloat(number).toFixed(decimals);
  const [float, dec] = fixed.split('.')
  const intFormatted = (+float)
  return intFormatted + (dec ? '.' + dec : '');
}


$(document).ready(function() {


  var tableData = {};
  var tabledata = {
    "ALMOND CHBAR~2402": {
      "itemName": "ALMOND CHBAR",
      "itemCode": "2402",
      "costPrice": 20.0,
      "gstPercentage": 14.5,
      "unitCode": "NOS",
      "mrp": 30.0
    },
    "A BR SB EX~333": {
      "itemName": "A BR SB EX",
      "itemCode": "333",
      "costPrice": 1.0,
      "gstPercentage": 0.0,
      "unitCode": "NOS",
      "mrp": 1.0
    }
  }

  populateData(tabledata)

  function rowappend(tbody) {

    const markup =
      `<tr>
									  <td>
									    <input type="text" class="form-control commanChange" id="itemNametd" name="itemNametd">
									  </td>
									  <td><input type="text" name="itemCodetd" id="itemCodetd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
									  <td><input type="text" name="mrptd" id="mrptd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
									  <td><input type="tel"  id="purRatetd"  class="form-control commantd"name="purRatetd"></td>
									  <td>
									    <input type="tel" id="unitQtytd"class="form-control commanChange" name="unitQtytd">
									  </td>
						               			 
									  <td>
									    <input type="tel" id="discPercentagetd"class="form-control commanChange" name="discPercentagetd" value="0.00">
									  </td>
									  <td><input type="text" name="discAmttd" id="discAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td> 
									  <td><input type="text" name="gstPercentagetd" id="gstPercentagetd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
									  <td><input type="text" name="gstAmttd" id="gstAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
									  <td><input type="text" name="totalAmttd" id="totalAmttd" class="form-control commantd" readonly="readonly" tabindex="-1"></td>
									  <input type="hidden" name="unittd" id="unittd" class="form-control commantd">
									  <td style="background-color: white;border: 1px white"><i class="fas fa-times fa-2x remove-btn" ></i></td>
									  
									</tr>`

    $(tbody).append(markup);
    setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

    var autoCompleteData = Object.keys(tableData);
    $("[name=itemNametd]", tbody).last().autocomplete({
      source: autoCompleteData,
      autoSelectFirst: true,
      autoFocus: true

    }).data('tableData', tableData);


  }


  function getValues(row) {
    const search = ($('[name=itemNametd]', row).val()).toString()

    var data = $('[name=itemNametd]', row).data('tableData');
    const value = data[search];

    if (value) {
      CostPrice = value.costPrice;
      $(row).find("[name=itemCodetd]").val(value.itemCode);
      $(row).find("[name=mrptd]").val(format(value.mrp));
      $(row).find("[name=purRatetd]").val(format(CostPrice));
      $(row).find("[name=unittd]").val(value.unitCode);
      $(row).find("[name=gstPercentagetd]").val(value.gstPercentage);
      $("[name=purRatetd]").focus();
    }

  }


  $(document).on("keyup", "[name=purRatetd]", function(e) {
    const row = e.target.parentElement.parentElement
    var unitQuantity = $(row).find("[name=unitQtytd]").val();

    var purchaseRate = $(row).find("[name=purRatetd]").val();
    var mrp = $(row).find("[name=mrptd]").val();
    totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate)) || 0;

    $(row).find("[name=totalAmttd]").val(format(totalAmount));

  });
  var subTotalAmt = 0;
  $(document).on("keyup", "[name=unitQtytd]", function(e) {

    const row = e.target.parentElement.parentElement
    unitQuantity = $(row).find("[name=unitQtytd]").val();

    purchaseRate = $(row).find("[name=purRatetd]").val();
    mrp = $(row).find("[name=mrptd]").val();
    totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate)) || 0;

    subTotalAmt += totalAmount || 0

    $(row).find("[name=totalAmttd]").val(format(totalAmount));
    $("#subTotalInput").val(format(subTotalAmt));
  });


  document.addEventListener("keydown", function(e) {
    const row = event.target.parentElement.parentElement

    var keycode = event.keyCode || event.which;
    if (keycode == '13') {
      if (!$(event.target).val()) {
        e.preventDefault();
        return;
      }
      const row = e.target.parentElement.parentElement
      if (event.target.matches('[name=discPercentagetd]')) {
        if ($(row).parent().find('tr').length - $(row).index() === 1) {
          rowappend(event.target.parentElement.parentElement.parentElement)
        }
      }
    }

  });

  $(document).on("focusout", "[name=itemNametd]", function(e) {
    const row = e.target.parentElement.parentElement
    getValues(e.target.parentElement.parentElement)
  });

  function populateData(data) {
    tableData = Object.assign({}, data);
    var autoCompleteData = Object.keys(data);
    rowappend($('tbody', '#tableInvoice'));


  }




});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-confirm/3.3.4/jquery-confirm.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css">
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="row tableGrn" id="commonDvScroll">
  <table class="table table-bordered" id="tableInvoice">
    <thead>
      <tr>
        <th id="itemNameth" class="commanth">Item Name</th>
        <th id="itemCodeth" class="commanth">I Code</th>
        <th id="mrpth" class="commanth">MRP</th>
        <th id="purRateth" class="commanth">Price</th>
        <th id="unitQtyth" class="commanth">Unit Qty</th>
        <th id="discPercentageth" class="commanth">Disc %</th>
        <th id="discAmtth" class="commanth">Disc Amt</th>
        <th id="gstPercentageth" class="commanth">GST %</th>
        <th id="gstAmtth" class="commanth">GST Amt</th>
        <th id="totalAmtth" class="commanth">Total Amt</th>

      </tr>
    </thead>
    <tbody>
    </tbody>

  </table>

</div>
<div class="form-row">

  <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
    <label for="subTotalInput">Sub Total</label>
    <div class="input-group">
      <input type="tel" class="form-control" aria-label="Text input with dropdown button" name="subTotalInput" id="subTotalInput" readonly="readonly" tabindex="-1">

    </div>
  </div>
</div>

注意-:请不要对 TotalAmt 列感到困惑,因为它是用于其他用途的,我将通过添加所有金额来做到这一点

现在我一直坚持按行计算 subTotal 并填充到输入字段中

Disc% 按下enter 时,它将创建一个新行

【问题讨论】:

  • 你能用 minimal 例子重现实际问题吗?不相关的代码太多了。
  • 看起来您根本没有重置subTotalAmt。要解决此问题,而不是在更改时添加每一行,只需重新计算整个列。除非您有 10,000 多行(无论如何这都是个坏主意),否则您不会注意到任何性能问题。
  • @freedomn-m 是的,我没有重置 subtotalAmt 我不知道该怎么做
  • 如果每次值更改时都添加到小计,那么您需要先删除旧值(因此您需要将旧值存储在隐藏字段或data-属性)不要在内存中保存运行总计,而只是重新计算所有值。

标签: javascript jquery html html-table


【解决方案1】:

请用以下代码替换您的代码

$(document).on("keyup", "[name=purRatetd],[name=unitQtytd]", function(e) {
    var unitQuantity = $(this).closest('tr').find("[name=unitQtytd]").val();
    var purchaseRate = $(this).closest('tr').find("[name=purRatetd]").val();
    var unitQuantity = unitQuantity ? unitQuantity : 1;
    var mrp = $(this).closest('tr').find("[name=mrptd]").val();
    totalAmount = (parseFloat(unitQuantity) * parseFloat(purchaseRate));
    $(this).closest('tr').find("[name=totalAmttd]").val(totalAmount);
    var subTotal = 0;
    $("[name=totalAmttd]").each(function(){
        var curVal = parseFloat($(this).val());
        if(curVal){
            subTotal = curVal + subTotal;
        }
    });
    $("#subTotalInput").val(subTotal);
});

N:B - 您在输入字段中使用 id 会在追加后一次又一次地重复,因此请避免使用 id 和 name...在整个代码中您可以使用 class 而不是 name 或 id...class name 可以相同,但 id 和 name 在多个字段中不能相同

【讨论】:

  • 您是说将价格和单位数量的产品存储到隐藏字段中?
  • 想想如果有人会通过单击右键来更改值,那么这将是一个问题,这不是专业行为,所以更改时更好地点击带有产品 ID 和数量的 ajax 请求,然后计算所有内容最终的服务器只是渲染客户端中的值
  • 您是说当用户选择任何项目名称时,我应该调用 AJAX 并调用所选项目的数据?
  • 否当改变数量时,您需要调用ajax请求参数将是产品ID和产品数量......然后在服务器中验证所有内容是否超过最大数量然后取通过查询从产品 id 获取产品价格,然后将产品价格乘以数量......作为响应,您将获得刚刚在客户端呈现的计算金额
  • 但是从服务器端它会非常复杂,有很多计算正在进行,假设用户选择一个项目名称,如果用户想要更改 unitQty,我将填充相应的数据,如果在同一行中那我应该怎么做,我只能在客户端做
猜你喜欢
  • 1970-01-01
  • 2012-07-23
  • 2023-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多