在提交表格时计算所有动态项目的总数,包括复制的项目

Calculate total of all dynamic items upon submit of form including copied items

本文关键字:项目 复制 包括 动态 表格 提交 计算所      更新时间:2023-09-26

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

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

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

$(".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();
}

那么现在会发生什么,您按 Tab 键或按 Enter 键循环浏览字段,在更新数量并按 Tab 键浏览后,它会更新该项目的总计以及总计。

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

//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...
});

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

请求 : (显示添加新行函数)

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++;
}

(获取值) 代码 :

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函数不会在total文本框上设置name属性。

但是,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>';

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

  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>';

请参阅下面的工作(但略微简化)片段:(或查看小提琴)

$(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()
input {
  width: 60px;
}
<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>

在这里,您正在change keyupblur上调用calculateTotal();函数events.只要您与表单元素交互,就可以工作。

但是,当您复制该行时,您将不会与这些更改、模糊和键控事件 textboxes.so 交互,因此calculateTotal()不会 executed.as 您看不到总价值的任何更新的结果。

要克服这个问题,您必须在复制函数中调用calculateTotal()