【问题标题】:jquery to sum two inputs on dynamic table and display in thirdjquery 对动态表上的两个输入求和并在第三个中显示
【发布时间】:2013-03-28 05:18:48
【问题描述】:

通过 SO 社区,我有一个脚本,可以将具有唯一名称的行添加到表中。我想在每一行取两个输入并将它们相乘并在第三个输入中显示结果。

小提琴在http://jsfiddle.net/yUfhL/231/

我的代码是: HTML

<table class="order-list">
  <tr><td>Product</td><td>Price</td><td>Qty</td><td>Total</td></tr>
  <tr>
      <td><input type="text" name="product" /></td>
      <td><input type="text" name="price" /></td>
      <td><input type="text" name="qty" /></td>
      <td><input type="text" name="linetotal" /></td>
    </tr>
</table>
<div id="grandtotal">
    Grand Total Here
</div>

JS

var counter = 1;
jQuery("table.order-list").on('change','input[name^="product"]',function(event){
    event.preventDefault();
    counter++;
    var newRow = jQuery('<tr><td><input type="text" name="product' +
        counter + '"/></td><td><input type="text" name="price' +
        counter + '"/></td><td><input type="text" name="qty' +
        counter + '"/></td><td><input type="text" name="total' +
        counter + '"/></td><td><a class="deleteRow"> x </a></td></tr>');
    jQuery('table.order-list').append(newRow);
});

jQuery("table.order-list").on('click','.deleteRow',function(event){

    $(this).closest('tr').remove();
});

$('table.order-list tr').each(function() {
   var price = parseInt( $('input[id^=price]', this).val(), 10 );
   var qty   = parseInt( $('input[id^=qty]'  , this).val(), 10 );
   $('input[id^=linetotal]', this).val(price * qty);
});

所以目前我无法让 js 获得两个单元格的乘积,即数量和价格。我想在 linetotal 中显示结果。

最后一部分是将所有 linetotals 的总和显示为 div grandtotal 中的总计

帮助一如既往地感激。

【问题讨论】:

  • 你只是给&lt;input&gt;元素一个name属性,但是使用id选择器([id^=price])。给他们一个特定的类比使用“id 开头”选择器要容易得多。此外,您希望何时计算总行数?您希望何时计算总计?在什么活动上?

标签: javascript jquery


【解决方案1】:

您只是给元素一个名称属性,但使用 id 选择器 ([id^=price])。给他们一个特定的类比使用“id 开头”选择器要容易得多。此外,您希望何时计算总行数?您希望何时计算总计?参加什么活动?

这是我对其外观的解释:

<table class="order-list">
    <thead>
        <tr><td>Product</td><td>Price</td><td>Qty</td><td>Total</td></tr>
    </thead>

    <tbody>
        <tr>
            <td><input type="text" name="product" /></td>
            <td>$<input type="text" name="price" /></td>
            <td><input type="text" name="qty" /></td>
            <td>$<input type="text" name="linetotal" readonly="readonly" /></td>
            <td><a class="deleteRow"> x </a></td>
        </tr>
    </tbody>

    <tfoot>
        <tr>
            <td colspan="5" style="text-align: center;">
                <input type="button" id="addrow" value="Add Product" />
            </td>
        </tr>

        <tr>
            <td colspan="5">
                Grand Total: $<span id="grandtotal"></span>
            </td>
        </tr>
    </tfoot>
</table>

还有 JS:

$(document).ready(function () {
    var counter = 1;

    $("#addrow").on("click", function () {
        counter++;

        var newRow = $("<tr>");
        var cols = "";
        cols += '<td><input type="text" name="product' + counter + '"/></td>';
        cols += '<td>$<input type="text" name="price' + counter + '"/></td>';
        cols += '<td><input type="text" name="qty' + counter + '"/></td>';
        cols += '<td>$<input type="text" name="linetotal' + counter + '" readonly="readonly"/></td>';
        cols += '<td><a class="deleteRow"> x </a></td>';
        newRow.append(cols);

        $("table.order-list").append(newRow);
    });

    $("table.order-list").on("change", 'input[name^="price"], input[name^="qty"]', function (event) {
        calculateRow($(this).closest("tr"));
        calculateGrandTotal();
    });

    $("table.order-list").on("click", "a.deleteRow", function (event) {
        $(this).closest("tr").remove();
        calculateGrandTotal();
    });
});

function calculateRow(row) {
    var price = +row.find('input[name^="price"]').val();
    var qty = +row.find('input[name^="qty"]').val();
    row.find('input[name^="linetotal"]').val((price * qty).toFixed(2));
}

function calculateGrandTotal() {
    var grandTotal = 0;
    $("table.order-list").find('input[name^="linetotal"]').each(function () {
        grandTotal += +$(this).val();
    });
    $("#grandtotal").text(grandTotal.toFixed(2));
}

http://jsfiddle.net/QAa35/

在您的 JS 中,您没有使用 linetotal 作为一个动态输入的 name。我还做了其他几个小的修改。您不妨使用&lt;thead&gt;&lt;tbody&gt;&lt;tfoot&gt;,因为您在&lt;table&gt; 中有这些部分。另外,我认为在“产品”输入更改时自动添加新行不是一个好的设计。这种情况经常发生,他们的意图可能不是添加新产品……按钮更友好。例如,假设您在第一个“产品”输入中键入“asdf”,然后单击某处。添加了一个新行。假设您打错了字,所以您返回并将其更改为“asd”,然后单击某处。添加了另一个新行。这似乎不对。

【讨论】:

  • 感谢伊恩,完美运行。感谢你的协助。我听到你在按钮而不是自动进入。我的设计在产品表上有一个自动完成功能,但它仍然可以创建多行,所以按钮是个好主意。谢谢。
  • a.deleteRow 只是为了帮助加快 jQuery 选择器进程。使用a 意味着选择所有&lt;a&gt; 元素(它是一个标记名选择器),然后按具有deleteRow 类的元素进行过滤。首先按标记名选择应该有助于加快速度(尽管可能不明显)。 a.deleteRow 的组合只是因为您知道具有类deleteRow 的元素肯定是&lt;a&gt;。如果您有多种元素标签,则必须删除a。但是你有一个特定的、已知的 HTML 结构,所以你可以使用它:)
  • 我有+row...,因为+ 是将字符串转换为数字的运算符。它实际上是在转换row.find('input[name^="price"]').val() 的结果,因为.val() 方法总是返回一个字符串。同时,稍后当我拥有price * qty 时,无论如何它们都应该自动转换(如果可能),因为* 运算符。所以从技术上讲,+s 是不必要的,我只是喜欢有时明确地做一些事情。
  • 我将+= 用于cols,因为它只是让它更具可读性。与其将var cols = "REALLY BIG STRING"; 放在一行上,从视觉上看,这样做更有意义。但它所做的只是将字符串连接成一个大字符串......但是在多行上这样做。
  • 是的,你完全正确,.val((price * qty).toFixed(2)) 是实际设置行总数的部分。它将价格乘以数量(显然),并将其转换为具有两位小数的字符串 (.toFixed(2))。然后它使用.val() 将文本框的值设置为结果。首先使用row.find() 的事实是针对刚刚更改的特定行,否则每次都必须循环遍历整个表。幸运的是,您可以知道哪些特定的文本框发生了变化(以及因此要更新/重新计算的特定行)。
【解决方案2】:

这个函数应该可以解决问题:

function updateGrandTotal() {

    var prices = [];
    $('input[name^="price"]').each(function () {
        prices.push($(this).val());
    });

    var qnts = [];
    $('input[name^="qty"]').each(function () {
        qnts.push($(this).val());
    });

    var total = 0;
    for(var i = 0; i < prices.length; i++){
        total += prices[i] * qnts[i];
    }

    $('#grandtotal').text(total.toFixed(2));

}

您只需将其绑定到表更改事件,以在每次输入更改时更新总计:

$("table.order-list").change(updateGrandTotal);

Here 是一个工作小提琴。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 2021-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2018-08-24
    相关资源
    最近更新 更多