计算每一行的变化

时间:2014-07-09 07:07:33

标签: javascript php jquery

我有一张发票表单来生成PDF。我希望在更改用户填写表单的值后计算输入。

我可以计算第一行,但我想(1)计算每一行,并在结束时(2)正确计算所有列。对于(1)的第一步,我将进行总计算。

问题是我生成了具有动态名称和id的行,因为我将它们以数组的形式发布到数据库中。对于此示例,每行输入的id都相同。

enter image description here

PS:我无法使.change工作,我使用$(document).on('change', '#qty', function (e) { calculateLine(); });来触发每个输入的计算功能。我不知道为什么.change不支持,最新的jquery。

[invoice.php]

<script>
    $(document).ready(function () {

        $(document).on('change', '#qty', function (e) { calculateLine(); });
        $(document).on('change', '#price', function (e) { calculateLine(); });
        $(document).on('change', '#discount', function (e) { calculateLine(); });
        $(document).on('change', '#discountPrice', function (e) { calculateLine(); });

    });
</script>

[invoice.js]

function calculateLine() {

    var qty = parseFloat($('#qty').val());
    var price = parseFloat($('#price').val());
    var discount = parseFloat($('#discount').val());
    var discountPrice = parseFloat($('#discountPrice').val());
    var vat = parseFloat($('#vat').val());

    var netTotal = 0;
    var total = 0;
    var vatAmount = 0;

    if (!qty && qty == 0) {
        return;
    }
    if (!price && price == 0) {
        return;
    }

    netTotal = qty * price;

    if ((!discount || discount == 0) && discountPrice != 0) {
        discount = (discountPrice / netTotal) * 100;
    }
    if ((!discountPrice || discountPrice == 0) && discount != 0) {
        discountPrice = (netTotal / 100) * discount;
    }
    if (discountPrice != 0 && discount != 0) {
        discountPrice = (netTotal / 100) * discount;
    }
    if ((!discount || discount == 0) && (!discountPrice || discountPrice == 0)) {
        discountPrice = 0;
        discount = 0;
    }

    total = netTotal - discountPrice;

    if (!total || total == 0) {
        total = 0;
    }
    vatAmount = (total / 100) * vat;

    $('#total').val(total);
    $('#discount').val(discount);
    $('#discountPrice').val(discountPrice);
    $('#vatAmount').val(vatAmount);

    //calculateTotal();
}

[HTML]

<tr>
    <td class="col-xs-0">
        <input type="checkbox" name="selected[]" class="checkall">
    </td>
    <td class="col-xs-5">
        <textarea type="text" name="invoice[item][{{j}}][description]" class="form-control description" rows="1" ></textarea>
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][unit]" class="form-control unit" value="" />
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][qty]" class="form-control qty" value="" />
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][price]" class="form-control price" value="" />
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][discount]" class="form-control discount" value="" >
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][discountPrice]" class="form-control discountPrice" />
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][total]" class="form-control total" value="" />
    </td>
    <td class="col-xs-1">
        <input type="text" name="invoice[item][{{j}}][vat]" class="form-control vat" value="{{invcl_vat}}" readonly />
        <input type="hidden" name="invoice[item][{{j}}][vatAmount]" class="form-control vatAmount" value="" readonly />
    </td>
</tr>

1 个答案:

答案 0 :(得分:2)

您尚未展示自己的HTML,但从您的问题可以清楚地看出,您在多个元素上使用相同的idqty等)。你不能这样做。页面上的每个id都必须唯一。在这种情况下,您可能会使用类。

你所做的事情的一般方式确实是使用委托事件处理,然后找到包含的行,并使用它作为查找使用类而不是id s的后代输入的起点:

$("selector-for-the-table").on("change", "input", function() {
    // Get the row containing the input
    var row = $(this).closest("tr");

    // Get the values from _this row's_ inputs, using `row.find` to
    // look only within this row
    var qty = parseFloat(row.find('.qty').val());
    var price = parseFloat(row.find('.price').val());
    var discount = parseFloat(row.find('.discount').val());
    var discountPrice = parseFloat(row.find('.discountPrice').val());
    var vat = parseFloat(row.find('.vat').val());

    // ...
});

我还在桌子上扎根,而不是document,所以它只适用于适当的地方。

Live (Simplified) Example

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
  <meta charset="utf-8">
  <title>Example</title>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><input type="text" class="qty"></td>
        <td><input type="text" class="price"></td>
        <td><input type="text" class="total" disabled></td>
      </tr>
      <!-- ...and so on... -->
    </tbody>
  </table>
<script>
  (function() {
    "use strict";

    $("table").on("change", "input", function() {
      var row = $(this).closest("tr");
      var qty = parseFloat(row.find(".qty").val());
      var price = parseFloat(row.find(".price").val());
      var total = qty * price;
      row.find(".total").val(isNaN(total) ? "" : total);
    });
  })();
</script>
</body>
</html>

你之前说过这些名字是动态的。当然,您尝试查找的字段的某些特征是一致的,或者您可以使它们保持一致。在最坏的情况下(我的意思是在最坏的情况下),你可以根据位置做一些事情 - 行中的第一个inputrow.find("input:eq(0)"),第二个是row.find("input:eq(1)"),所以上。

Live Example Using eq

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
  <meta charset="utf-8">
  <title>Example</title>
</head>
<body>
  <table>
    <thead>
      <tr>
        <th>Quantity</th>
        <th>Price</th>
        <th>Total</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><input type="text"></td>
        <td><input type="text"></td>
        <td><input type="text" disabled></td>
      </tr>
      <!-- ...and so on... -->
    </tbody>
  </table>
<script>
  (function() {
    "use strict";

    $("table").on("change", "input", function() {
      var row = $(this).closest("tr");
      var qty = parseFloat(row.find("input:eq(0)").val());
      var price = parseFloat(row.find("input:eq(1)").val());
      var total = qty * price;
      row.find("input:eq(2)").val(isNaN(total) ? "" : total);
    });
  })();
</script>
</body>
</html>

但是如果可能的话,请避免使用它,这很脆弱 - 如果更改列的顺序,则必须更改代码。