当我添加行的值时,JavaScript出现了一个奇怪的错误

JavaScript strange error when I am doing adding the values of row?

本文关键字:错误 一个 添加行 JavaScript      更新时间:2023-09-26

我的JavaScript代码中有一个奇怪的错误。我的标记是这样的:

<table id="invoice-details">
  <tbody id="tableToModify">
  <?php
    $i=1;
    while($i<2){
  ?>
    <tr>
      <td>
        <input type="hidden" name="prdid[]" id="prd_id<?php echo $i; ?>" />
          <input type="text" tabindex="<?php echo 2+($i*5);?>"  name="prdname[]" id="prd_name<?php echo $i; ?>" />
      </td>
      <td>
        <input type="text" name="prddesc[]" id="prd_desc<?php echo $i; ?>" disabled="disabled" />
       </td>
       <td>
        <input type="text" name="prdcost[]" id="prd_cost<?php echo $i; ?>" value="0" disabled="disabled" style="color:#333;" />
       </td>
       <td>
        <input type="text" name="prdquentity[]" id="prd_quentity<?php echo $i; ?>" tabindex="<?php echo 3+($i*5);?>" onKeyUp="calprice1(this.value,'<?php echo $i; ?>');" value="1" />
       </td>
       <td>
        <input type="text" name="prddamount[]" tabindex="<?php echo 5+($i*5);?>" readonly="true" id="prd_damount<?php echo $i; ?>" onKeyUp="calprice2(this.value,'<?php echo $i; ?>');"  />
       </td>
       <td id="readonly">
        <input readonly="readonly" name="prdprice[]" id="prd_price<?php echo $i; ?>" value="0" />
       </td>
      </tr>
      <?php
      $i++;
      }
      ?>
    </tbody>
  </table><!--#invoice-details-->

现在,我有一个名为添加新行的按钮。标记如下:

 <input type="button" style="float:left;" onClick="createRow();" class="add-line" value="Add a new line">

为此,我制作了这样的JavaScript:

function createRow()
    {
      //var newlineno=document.forms[0].elements["prdprice[]"].length;
      var newlineno = document.querySelectorAll("[name='prdprice[]']").length
      newlineno++;
      //console.log(newlineno);
      var row = document.createElement('tr'); 
      var col1 = document.createElement('td');
      var col2 = document.createElement('td');
      var col3 = document.createElement('td'); 
      var col4 = document.createElement('td');
      var col5 = document.createElement('td'); 
      var col6 = document.createElement('td'); 
      var col7 = document.createElement('td'); 
      
      row.appendChild(col1); 
      row.appendChild(col2);
      row.appendChild(col3); 
      row.appendChild(col4);
      row.appendChild(col5); 
      row.appendChild(col6);
      row.appendChild(col7); 
      
      col1.innerHTML = "<input type='"hidden'" name='"prdid[]'" id='"prd_id"+newlineno+"'" /><input type='"text'" name='"prdname[]'" id='"prd_name"+newlineno+"'" autocomplete='"off'" onKeyUp='"producthint(this.value,'"+newlineno+"');'" /><div id='"prd"+newlineno+"'" style='"position:absolute;'"></div>";
      col2.innerHTML = "<input type='"text'" disabled='"disabled'" name='"prddesc[]'" id='"prd_desc"+newlineno+"'" />";
      col3.innerHTML = "<input type='"text'" disabled='"disabled'" name='"prdcost[]'" id='"prd_cost"+newlineno+"'" value='"0'" />";
      col4.innerHTML = "<input type='"text'" name='"prdquentity[]'" id='"prd_quentity"+newlineno+"'" onKeyUp='"calprice1(this.value,'"+newlineno+"');'" value='"1'" />";
      col5.innerHTML = "<select name='"prddtype[]'" class='"discount-type'" id='"prd_dtype"+newlineno+"'" >"+document.getElementById("prd_dtype1").innerHTML+"</select>";
      col6.innerHTML = "<input type='"text'" name='"prddamount[]'" id='"prd_damount"+newlineno+"'" onKeyUp='"calprice2(this.value,'"+newlineno+"');'"  />";
      col7.innerHTML = "<input readonly='"readonly'" name='"prdprice[]'" id='"prd_price"+newlineno+"'" value='"0'" />";
      
      var table = document.getElementById("tableToModify"); // find table to append to
      table.appendChild(row); // append row to table
    }  

到目前为止一切都很好。现在,当我试图在第一列中插入一个产品名称,并且从数据库中填充值时,它应该显示计算结果。对于计算,我做了js,比如:

function calprice1(q,line) {
  var cost=document.getElementById("prd_cost"+line).value;
  var damount=document.getElementById("prd_damount"+line).value;
  document.getElementById("prd_price"+line).value=parseFloat((cost*q)*(100-damount)/100).toFixed(2);
  totalprice();
 }

现在,对于底部的总价,其中将添加单个价格的所有价格,我使用总价函数。功能是这样的:

 function totalprice(){
  var sum=0;
  var price = document.forms[0].elements["prdprice[]"];
  console.log(price);
  for(var i=0, n=price.length;i<n;i++) {
  sum+=parseFloat(price[i].value);
  }
  document.getElementById("total").innerHTML=parseFloat(sum).toFixed(2);
  
  }
  

现在,计算完成后第一行的值没有显示在totalprice中,但当我通过addrow按钮添加另一行时,它显示了具有正确数量的totalprice(所有行的值都被添加)。有人能告诉我这里有什么问题吗?我们非常感谢您的帮助和建议。

现在,在这里,计算完成后第一行的值没有显示在totalprice中,但当我通过addrow按钮添加另一行时,它显示的是具有正确金额的totalprize(所有行的值都被添加)。

所以在开头,您只有一行,因此只有一个名为prdprice[]的表单元素,对吗?

好吧,这就是问题所在:如果有多个元素使用该名称,则document.forms[0].elements["prdprice[]"]返回NodeList——否则,它将直接返回对单个DOM节点的引用。

因此,当您获得对单个DOM节点的引用时,它没有length属性,并且通过尝试读取它,您将只获得undefined

由于0 < undefined的计算结果为false,所以for循环不会在单个时间内迭代…

<小时>

解决这个问题的一个简单方法是:

var price = document.forms[0].elements["prdprice[]"];
if(price.length === undefined) { price = [price]; }

如果price不是NodeList,而是对单个DOM节点的引用,那么我们将其作为一个数组,其中包含对该单个DOM节点作为其唯一元素的引用。

在那之后,price在任何情况下都有一个length,所以您可以使用for循环对其进行循环,就像它是NodeList一样。

不过有一个漏洞:由于我们在这里创建了一个数组,它的行为与NodeList不同。NodeList是"活动的",这意味着DOM中的任何更改都会立即被它们反映出来——而我们的数组是静态的。但是,只要您没有向DOM添加/删除节点(这个NodeList将"捕获"的节点,因此只有名称为prdprice[]的该形式的元素),而是在以前存在的元素上循环,这就无关紧要了。

相关文章: