javascript - 提交表单后计算所有动态项目的总数,包括复制的项目

标签 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();
}

那么现在会发生什么,您按 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...
});

复制的行不会在总数上更新。这让我发疯,有人有解决方案或教程吗?

请求:(显示 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;
    };

(设置值):

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

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

$(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>

关于javascript - 提交表单后计算所有动态项目的总数,包括复制的项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35507738/

相关文章:

javascript - Array.prototype.filter() 的就地替代方法是什么

php - 如何以与子句中给定的顺序相同的顺序获取查询结果

php - 获取过去某个时间点的粉丝页面的 Facebook 点赞数

javascript - 找不到合适的选择器

javascript - 在 HTML 中检索 MySQL 图像 Blob

Javascript 获得 MIME 类型支持

javascript整个页面飞进飞出的效果?

php - json_encode 数组的问题

javascript - 如何在用于在网页中播放 .swf 的 Flash 播放器中使用控件?

javascript - 需要测验应用程序一次只显示一个项目