Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/429.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用动态生成的行更新字段时出错_Javascript_Jquery_Autocomplete - Fatal编程技术网

Javascript 使用动态生成的行更新字段时出错

Javascript 使用动态生成的行更新字段时出错,javascript,jquery,autocomplete,Javascript,Jquery,Autocomplete,我有库存表格,可以将库存提交到数据库。我在更新动态生成行的单位成本和总成本时遇到了一个问题。正如您在下面的快照中所看到的。产品名称通过自动完成jQuery获取 HTML代码 我还需要将“运输成本”输入字段放在表格底部,并显示发票的总计。页面和代码存在多个问题,因此我将尽我所能进行说明@Barmar还发现了其他问题,因此将尝试涵盖所有问题,并提出一些改进建议 JSFiddle: 模板: 与在代码中使用文本字符串相比,将HTML维护为HTML更容易。我提供的示例使用了一个类型为text/templa

我有库存表格,可以将库存提交到数据库。我在更新动态生成行的单位成本和总成本时遇到了一个问题。正如您在下面的快照中所看到的。产品名称通过自动完成jQuery获取

HTML代码
我还需要将“运输成本”输入字段放在表格底部,并显示发票的总计。

页面和代码存在多个问题,因此我将尽我所能进行说明@Barmar还发现了其他问题,因此将尝试涵盖所有问题,并提出一些改进建议

JSFiddle:

模板:

与在代码中使用文本字符串相比,将HTML维护为HTML更容易。我提供的示例使用了一个类型为text/template的伪脚本块,所有浏览器都会忽略它,但您可以使用$'template'.HTML访问HTML内容

重复的ID无效


页面中不能有重复的ID。这是无效的HTML,jQuery将只看到第一个匹配项。在添加的元素上使用类,并在这些元素上进行匹配

因此,请使用:

<a class="remScnt" 
注意:您还需要整理任何其他重复id,如产品id、数量、成本和总额。您的代码已经使用了这些类,所以只需移动/删除id属性即可

e、 g.对任何事情都使用类:

    scntDiv.append('<tr>'+
    '<td>'+i+'</td>'+
    '<td><input class="product_id" type="text" name="product_id[]" hidden><input id="product_code" type="text" name="product_code[]" hidden><input class="product_name form-control" type="text" placeholder="Type product name/code here" name="products[]" required></td>'+
    '<td><input class="quantity form-control" type="text" placeholder="Quantity to Buy" name="quantity[]" required /></td>'+
    '<td><div class="input-group"><span class="input-group-addon">$</span><input class="cost form-control" placeholder="Unit Cost" type="text" readonly /></div></td>'+
    '<td><div class="input-group"><span class="input-group-addon">$</span><input class="total form-control" placeholder="Total" type="text" readonly /></div></td>'+
    '<td><a class="remScnt btn btn-danger btn-xs"><span title="Delete" class="glyphicon glyphicon-remove"></span></a></td>'+
    '</tr>');
重要提示:此处的代码与特定行不匹配。还可以使用@Barmar的如下修复来传递当前行:

更新:正如Regent在下面提到的,您不应该使用文档,而应该为您的委托事件处理程序使用p_气味:

$('#p_scents').on('click', '.remScnt', function() 
如果方便/可用,委托事件应附加到最近的未更改祖先。这将提供一个非常小的速度增加,因为它停止在DOM较低的位置

我还清理了执行计算的事件处理程序,该计算现在使用temp vars,用于与行相关的元素,如下所示:

// Update the row total of a specific row
var updateTotal = function ($row) {
    // Get the specific inputs
    var $quantity = $('.quantity', $row);
    var $cost = $('.cost', $row);
    var $total = $('.total', $row);
    var input1 = parseFloat($quantity.val());
    var input2 = parseFloat($cost.val());
    if (isNaN(input1) || isNaN(input2)) {
        if (!input2) {
            $total.val($quantity.val());
        }

        if (!input1) {
            $total.val($cost.val());
        }

    } else {
        $total.val(input1 * input2);
    }
    var total = input1 * input2;
    $total.val(total);
};
注意:如果没有丢失的数据,我无法轻松地测试代码,但您应该了解这一点

总计

要更新总计,您需要迭代所有.total字段并将其添加到运输成本中:

   var updateGrandTotal = function()
   {
       // Now update the grand total
       var grandTotal = 0;
       $('.total').each(function () {
           grandTotal += parseFloat($(this).val());
       });
       var shipping = parseFloat($('.shippingcost').val());
       $('.grandtotal').val(grandTotal + shipping);
   }
由于您希望在发货更改时更新总计,因此我对其进行了重构,以便也可以从发货上的键控调用它:

   $('.shippingcost').keyup(function(){
       updateGrandTotal();
   });
另一个问题是自动完成,如果没有真正的数据源,我无法测试它:

基本上,获取select事件以引用当前字段的行,并找到要更新的适当字段:

JSFiddle:

当updateTotal使用$'.quantity.val时,它获取该类的第一个字段的值,而不是用户键入的行中的值。您需要将该行传递给函数。此外,由于元素是动态添加的,因此需要对事件绑定使用委托

$('#p_scents').on('keyup', '.quantity, .cost', function() {  
    updateTotal($(this).closest('tr'));
});

var updateTotal = function (row) {
    var input1 = parseFloat($('.quantity', row).val());
    var input2 = parseFloat($('.cost', row).val());
    if (isNaN(input1) || isNaN(input2)) {
        if(!input2){
            $('.total', row).val(input1);
        }

        if(!input1){
            $('.total', row).val($(input2);
                                }

        } else {          
            $('.total', row).val(input1 * input2);
        }
    }
    var output_total = $('.total', row);
    var total = input1 + input2;
    output_total.val(total);

};

页面中不能有重复的ID。这是无效的HTML,jQuery将只看到第一个匹配项。在添加的元素上使用类,并在这些元素上进行匹配。为什么要将if中的输入相乘,但在if完成后再添加它们?如果两个数字都是NaN,为什么要将它们相乘呢?要获得更好的代码,还有一件事:$'p_scents'。单击,'.remScnt',函数{性能会稍微好一点。@Regent:已批准并更新。对于任何鼠标事件,性能差异都可以忽略不计,但这是一个很好的实践。好吧,是的,实践在那里更合适:我实际上没有检查OP中的原始代码,但可以很容易地相信6个。@DJ MHA:现在已完成更新。如果有任何mo,请告诉我re问题悬而未决,因为在我的示例中当然没有数据:@DJ MHA:刚回来。在上一个版本中有一些打字错误,我删除了额外的总计选择器,因为它无效,不适用于行,也不需要。产品列表为空,但我已硬连线了测试的项目价格:干杯。使用您的解决方案添加项目d自动竞争不起作用。请用完整的代码更新您的答案好吗?
$('#p_scents').on('keyup', '.quantity .cost', function() {  
    updateTotal();
});
$('#p_scents').on('keyup', '.quantity .cost', function() {  
    updateTotal($(this).closest('tr'));
});
$('#p_scents').on('click', '.remScnt', function() 
// Update the row total of a specific row
var updateTotal = function ($row) {
    // Get the specific inputs
    var $quantity = $('.quantity', $row);
    var $cost = $('.cost', $row);
    var $total = $('.total', $row);
    var input1 = parseFloat($quantity.val());
    var input2 = parseFloat($cost.val());
    if (isNaN(input1) || isNaN(input2)) {
        if (!input2) {
            $total.val($quantity.val());
        }

        if (!input1) {
            $total.val($cost.val());
        }

    } else {
        $total.val(input1 * input2);
    }
    var total = input1 * input2;
    $total.val(total);
};
   var updateGrandTotal = function()
   {
       // Now update the grand total
       var grandTotal = 0;
       $('.total').each(function () {
           grandTotal += parseFloat($(this).val());
       });
       var shipping = parseFloat($('.shippingcost').val());
       $('.grandtotal').val(grandTotal + shipping);
   }
   $('.shippingcost').keyup(function(){
       updateGrandTotal();
   });
   select: function (evt, ui) {
       // when a product is selected, populate related fields in this form
       var $tr = $(this).closest("tr");
       $(".cost",$tr).val(ui.item.cost);
       $(".product_id", $tr).val(ui.item.product_id);
       $(".product_code", $tr).val(ui.item.product_code);
   }
$('#p_scents').on('keyup', '.quantity, .cost', function() {  
    updateTotal($(this).closest('tr'));
});

var updateTotal = function (row) {
    var input1 = parseFloat($('.quantity', row).val());
    var input2 = parseFloat($('.cost', row).val());
    if (isNaN(input1) || isNaN(input2)) {
        if(!input2){
            $('.total', row).val(input1);
        }

        if(!input1){
            $('.total', row).val($(input2);
                                }

        } else {          
            $('.total', row).val(input1 * input2);
        }
    }
    var output_total = $('.total', row);
    var total = input1 + input2;
    output_total.val(total);

};