计算提交表格(包括复制的项目)后所有动态项目的总和

时间:2016-02-19 14:32:49

标签: javascript php jquery forms

我正在尝试计算动态表单选项列表的总和,例如:

产品名称 产品描述 数量 价钱 总

我有一个自动添加项目行的脚本:

$(".addmore").on('click',function(){
    html = '<tr>';
    html += '<td><input class="case" type="checkbox"/></td>';
    html += '<td><input type="text" data-type="productCode" name="data[Invoice][itemNo][]" id="itemNo_'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '<td><input type="text" data-type="productName" name="data[Invoice][itemName][]" id="itemName_'+i+'" class="form-control" autocomplete="off"></td>';
    html += '<td><input type="text" name="data[Invoice][price][]" id="price_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="text" name="data[Invoice][quantity][]" id="quantity_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="text" name="data[Invoice][total][]" id="total_'+i+'" class="form-control totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input class="case" type="checkbox" name="data[Invoice][staged][]" id="itemStaged_'+i+'"></td>';
    html += '</tr>';
    $('table').append(html);
    i++;
});

和执行总计的脚本:

$(document).on('change keyup blur','#tax',function(){
    calculateTotal();
});

//total price calculation 
function calculateTotal(){
    subTotal = 0 ; total = 0; 
    $('.totalLinePrice').each(function(){
        if($(this).val() != '' )subTotal += parseFloat( $(this).val() );
    });
    $('#subTotal').val( subTotal.toFixed(2) );
    tax = $('#tax').val();
    if(tax != '' && typeof(tax) != "undefined" ){
        taxAmount = subTotal * ( parseFloat(tax) /100 );
        $('#taxAmount').val(taxAmount.toFixed(2));
        total = subTotal + taxAmount;
    }else{
        $('#taxAmount').val(0);
        total = subTotal;
    }
    $('#totalAftertax').val( total.toFixed(2) );
    calculateAmountDue();
}

那么现在发生了什么,你选择或按回车键遍历字段,更新数量和标签后,它会更新该项目的总数以及总计。

问题在于,如果您使用以下脚本复制和粘贴表单字段:

//copies the selected table rows to new ones
$(".copy").on('click', function() {
    var origs=$('.case:checkbox:checked');
    for(var a=0; a<origs.length; a++) {
        addNewRow();
        var arr = origs.closest('tr')[a].id.split('_');
        var id = arr[arr.length-1];
        var dat = getValues(id);
        setValues(i-1, dat);
    }
    $('#check_all').add(origs).prop("checked", false);
    // Tried adding calculateTotal(); in this line to no avail...
});

复制的行不会在总计上更新。这让我感到疯狂,是否有人有关于如何做到这一点的解决方案或教程?

请求:(显示addNewRow函数)

var addNewRow = function(id){
    html = '<tr id="tr_'+i+'">';
    html += '<input type="hidden" id="stock_'+i+'"/>';
    html += '<input type="hidden" id="stockMaintainer_'+i+'" name="data[InvoiceDetail]['+i+'][stockMaintainer]" />';
    html += '<input type="hidden" id="previousQuantity_'+i+'"/>';
    html += '<input type="hidden" id="invoiceDetailId_'+i+'"/>';
    html += '<td><input class="case" id="caseNo_'+i+'" type="checkbox" onkeyup="return tabE(this,event);"/></td>';
    html += '<td class="prod_c"><input type="text" data-type="productCode" name="data[InvoiceDetail]['+i+'][product_id]" id="itemNo_'+i+'" class="form-control autocomplete_txt" autocomplete="off" onkeyup="return tabE(this,event);">';
    html +='<span class="add_icon" id="add_icon_'+i+'"> <i class="fa fa-plus-circle"></i></span>';
    html +='<span class="subtract_icon" id="subtract_icon_'+i+'"><i class="fa fa-minus-circle"></i></span>';
    html +='</td>';
    html += '<td><input type="text" data-type="productName" name="data[InvoiceDetail]['+i+'][productName]"  id="itemName_'+i+'" class="form-control" autocomplete="off" onkeyup="return tabE(this,event);"></td>';
    html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][price]" id="price_'+i+'" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="text" name="data[InvoiceDetail]['+i+'][quantity]" id="quantity_'+i+'" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;">';
    html += '</td>';
    html += '<td><input type="text" id="total_'+i+'" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="checkbox" name="data[InvoiceDetail]['+i+'][staged]" id="staged_1'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '<td><input type="checkbox" name="data[InvoiceDetail]['+i+'][added]" id="added_1'+i+'" class="form-control autocomplete_txt" autocomplete="off"></td>';
    html += '<td><select name="data[InvoiceDetail]['+i+'][location]" id="location_1'+i+'" class="form-control autocomplete_txt" autocomplete="off">';
    html += '<option value="Used">Used</option>';
    html += '<option value="RTS">RTS</option>';
    html += '<option value="LAJ">LAJ</option>';
    html += '</select></td>';
    html += '</tr>';

    if( typeof id !== "undefined"){
        $('#tr_'+id).after(html);
    }else{
        $('table').append(html);
    }
    $('#caseNo_'+i).focus();
    i++;
}

(getValues)代码:

var getValues=function(id){
        var inputs=$('#tr_'+id).find('select,input,textarea').filter('[name]');
        var values={};
        for(var i=0; i<inputs.length;i++){
            var cur=inputs[i];
            values[cur.name.match(/\[\w+]$/)||cur.name] = $(cur).is(':checkbox, :radio') ? cur.checked : cur.value;
        }
        return values;
    };

(setValues):

var setValues=function(id,values){
        var inputs=$('#tr_'+id);
        for(var i in values){
            var cur=inputs.find('[name$="'+i+'"]');
            if(cur.is(':checkbox, :radio')) {
                cur.prop('checked', values[i]);
            } else {
                cur.val(values[i]);
            }
        }
    };

2 个答案:

答案 0 :(得分:1)

addNewRow功能未在name文本框中设置total属性。

但是,您的getValuessetValues函数正在使用[name]属性选择器来获取和设置克隆行中的值。由于addNewRow未设置name属性,因此总值无法填充克隆行,因此总数不会更改,因为calculateTotal会将此值解释为0

问题代码在这里:

  html += '<td><input type="text" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';

以下是固定的代码行:(并且还记得在calculateTotal处理程序中调用copy

  html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][total]" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';

请参阅下面的工作(但略微简化)代码段:(or see the fiddle

&#13;
&#13;
$(document).on('change keyup blur', '#tax', function() {
  calculateTotal();
});
IsNumeric = tabE = function() {
  return true
}
var i = 0;

var addNewRow = function(id) {
  var html = '<tr id="tr_' + i + '">';
  html += '<input type="hidden" id="stock_' + i + '"/>';
  html += '<input type="hidden" id="stockMaintainer_' + i + '" name="data[InvoiceDetail][' + i + '][stockMaintainer]" />';
  html += '<input type="hidden" id="previousQuantity_' + i + '"/>';
  html += '<input type="hidden" id="invoiceDetailId_' + i + '"/>';
  html += '<td><input class="case" id="caseNo_' + i + '" type="checkbox" onkeyup="return tabE(this,event);"/></td>';
  html += '<td class="prod_c"><input type="text" data-type="productCode" name="data[InvoiceDetail][' + i + '][product_id]" id="itemNo_' + i + '" class="form-control autocomplete_txt" autocomplete="off" onkeyup="return tabE(this,event);">';
  html += '<span class="add_icon" id="add_icon_' + i + '"> <i class="fa fa-plus-circle"></i></span>';
  html += '<span class="subtract_icon" id="subtract_icon_' + i + '"><i class="fa fa-minus-circle"></i></span>';
  html += '</td>';
  html += '<td><input type="text" data-type="productName" name="data[InvoiceDetail][' + i + '][productName]"  id="itemName_' + i + '" class="form-control" autocomplete="off" onkeyup="return tabE(this,event);"></td>';
  html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][price]" id="price_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;"></td>';
  html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][quantity]" id="quantity_' + i + '" class="form-control changesNo quanyityChange" autocomplete="off" onkeypress="return IsNumeric(event);" onkeyup="return tabE(this,event);" ondrop="return false;" onpaste="return false;">';
  html += '</td>';
  html += '<td><input type="text" name="data[InvoiceDetail][' + i + '][total]" id="total_' + i + '" class="form-control totalLinePrice addNewRow" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
  html += '<td><input type="checkbox" name="data[InvoiceDetail][' + i + '][staged]" id="staged_1' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
  html += '<td><input type="checkbox" name="data[InvoiceDetail][' + i + '][added]" id="added_1' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
  html += '<td><select name="data[InvoiceDetail][' + i + '][location]" id="location_1' + i + '" class="form-control autocomplete_txt" autocomplete="off">';
  html += '<option value="Used">Used</option>';
  html += '<option value="RTS">RTS</option>';
  html += '<option value="LAJ">LAJ</option>';
  html += '</select></td>';
  html += '</tr>';

  if (typeof id !== "undefined") {
    $('#tr_' + id).after(html);
  } else {
    $('table').append(html);
  }
  $('#caseNo_' + i).focus();
  i++;
}

$(".addmore").on('click', function() {
  html = '<tr>';
  html += '<td><input class="case" type="checkbox"/></td>';
  html += '<td><input type="text" data-type="productCode" name="data[Invoice][itemNo][]" id="itemNo_' + i + '" class="form-control autocomplete_txt" autocomplete="off"></td>';
  html += '<td><input type="text" data-type="productName" name="data[Invoice][itemName][]" id="itemName_' + i + '" class="form-control" autocomplete="off"></td>';
  html += '<td><input type="text" name="data[Invoice][price][]" id="price_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
  html += '<td><input type="text" name="data[Invoice][quantity][]" id="quantity_' + i + '" class="form-control changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
  html += '<td><input type="text" name="data[Invoice][total][]" id="total_' + i + '" class="form-control totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
  html += '<td><input class="case" type="checkbox" name="data[Invoice][staged][]" id="itemStaged_' + i + '"></td>';
  html += '</tr>';
  $('table').append(html);
  i++;
});

//copies the selected table rows to new ones
$(".copy").on('click', function() {
  var origs = $('.case:checkbox:checked');
  for (var a = 0; a < origs.length; a++) {
    addNewRow();
    var arr = origs.closest('tr')[a].id.split('_');
    var id = arr[arr.length - 1];
    var dat = getValues(id);
    setValues(i - 1, dat);
  }
  $('#check_all').add(origs).prop("checked", false);
  calculateTotal();
});

//total price calculation 
function calculateTotal() {
  subTotal = 0;
  total = 0;
  $('.totalLinePrice').each(function() {
    if ($(this).val() != '') subTotal += parseFloat($(this).val());
  });
  $('#subTotal').val(subTotal.toFixed(2));
  tax = $('#tax').val();
  if (tax != '' && typeof(tax) != "undefined") {
    taxAmount = subTotal * (parseFloat(tax) / 100);
    $('#taxAmount').val(taxAmount.toFixed(2));
    total = subTotal + taxAmount;
  } else {
    $('#taxAmount').val(0);
    total = subTotal;
  }
  $('#totalAftertax').val(total.toFixed(2));
  //calculateAmountDue();
}

var getValues = function(id) {
  var inputs = $('#tr_' + id).find('select,input,textarea').filter('[name]');
  var values = {};
  for (var i = 0; i < inputs.length; i++) {
    var cur = inputs[i];
    values[cur.name.match(/\[\w+]$/) || cur.name] = $(cur).is(':checkbox, :radio') ? cur.checked : cur.value;
  }
  return values;
};

var setValues = function(id, values) {
  var inputs = $('#tr_' + id);
  for (var i in values) {
    var cur = inputs.find('[name$="' + i + '"]');
    if (cur.is(':checkbox, :radio')) {
      cur.prop('checked', values[i]);
    } else {
      cur.val(values[i]);
    }
  }
};

addNewRow()
addNewRow()
&#13;
input {
  width: 60px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  Tax rate
  <input type="text" id="tax" value="8.7">
</div>
<div>
  Tax amt
  <input type="text" id="taxAmount" value="0">
</div>
<div>
  Total
  <input type="text" id="totalAftertax" value="0">
</div>
<a href="javascript:;" class="copy">COPY CHECKED ROWS (check some rows first)</a>
<table>
  <thead>
    <tr>
      <th>copy</th>
      <th>product code</th>
      <th>product name</th>
      <th>price</th>
      <th>qty</th>
      <th>total</th>
      <th>staged</th>
      <th>added</th>
      <th>location</th>
    </tr>
  </thead>
</table>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

您在calculateTotal(); changekeyup致电blur函数 events.this只要你与表单元素交互就可以工作。

但是当你复制该行时,你不会与textboxes进行交互。因此,这些更改,模糊和键盘事件不会被触发,因此calculateTotal() 将不会执行。因此您无法看到总价值的任何更新。

要克服这个问题,你必须在复制功能中调用calculateTotal()