首页 > 解决方案 > 动态生成 HTML

问题描述

我是一个绝对的初学者,已经自学了两周,为一个月后的训练营做准备。为了提高我的技能并“学会像开发人员一样思考”,我承担了一个试图解决现实世界问题的项目。

我的妻子经营一家企业,要求她为客户开具发票。我正在尝试使用 HTML 和 JavaScript 来构建一个基于 Web 的应用程序,这使她能够快速创建自定义发票,而不是每次都手动将它们写出来。

在当前版本中,提示要求她提供一个号码。此数字在 HTML 中生成相同数量的三列行。这使她能够使用她需要的确切字段数自定义发票。

第 1 列包含产品名称。在同一行中,第 2 列包含单位数量,而第 3 列包含该产品的总成本,即基本价格乘以单位数量。我希望在单击按钮时进行此计算。但是,我被困住了。

为了执行数学运算,我需要能够从每一行和每一列中获取整数并将它们传递给一个函数。但是因为每一行和每一列都是自动生成的,它们没有唯一的属性,因此无法识别。我能够在每一列中执行数学运算,但不能在每一行中执行。

由于我是新手,只从几个介绍性 Codecademy 课程和一些 YouTube 视频中学习,我不知道如何评估我是否完全错误地接近该项目,或者我是否缺少一些技巧,或者如果还有一些东西还没有学到。如果有一些专业知识的人可以将我推向正确的方向,我将不胜感激!

我已将所有代码附加到这篇文章中。抱歉,如果这是一个可怕的混乱。放轻松,我是初学者!

const invDate = Date();
var field = "<label for='Item'>Item:</label> <input type=text name='item'>" +             
"<label for='qty'> Qty: </label> <input type='number' name='qty'>" + 
"<label for='Price'> Price ($):</label> <input type='number' name='price'> <br><br>";

document.getElementById('newInvoice').onclick = function(){

  let invoicedName = prompt('Who is this invoice made out to?', 'Enter a name');
  let productFields = Number(prompt('How many product names on this invoice?', 'Please enter a number'));  
  let fields = ''
  let dynHtml = ''
      if (invoicedName != null && productFields != null) {                                          
      for (let i = 1; i <= productFields; i++) { 
      fields += field };
    } else { alert('Please enter valid inputs.'); 
  };
  dynHtml = "<center><img src ='logo.jpg'><br></br>" +                                              
            "<h1>INVOICE</h1>" +
            "<p>Prepared for: <b>" + invoicedName + "</b>, on" +
            "<p>" + invDate + "</p><br></br>" +
            fields + "<br></br>" +
            "<button id ='calculate'>Calculate</button></center>";
  document.write(dynHtml);
                                                                                                    
  document.getElementById('calculate').onclick = function getQtyFields() {
      
    let qtyInputs = document.getElementsByName('qty'),
          resultQty = 0;
      for ( let j = 0; j < qtyInputs.length; j++ ) {
          if ( qtyInputs[j].id.indexOf('qty') == 0 ) {
              let num = parseFloat( qtyInputs[j].value );
              if( !isNaN(num) ) resultQty += num;
          }
      }
    let priceInputs = document.getElementsByName('price'),
          resultPrice = 0;
      for( let k = 0; k < priceInputs.length; k++ ) {
          if( priceInputs[k].id.indexOf('price') == 0 ) {
              let num = parseFloat( priceInputs[k].value );
              if( !isNaN(num) ) resultPrice += num;
          }
      }
      alert(resultQty); alert(resultPrice)
  }
}

这是截图, 截屏

标签: javascripthtmlloops

解决方案


正如您所说,您的主要问题是找到一种方法,让他们自己的行中的每个输入字段都有自己的唯一标识符。这样,您可以计算每行的价格并将其插入价格字段。

您首先必须从以下字段开始:

var field = "<label for='Item'>Item:</label> <input type=text name='item'>" +             
"<label for='qty'> Qty: </label> <input type='number' name='qty'>" + 
"<label for='Price'> Price ($):</label> <input type='number' name='price'> <br><br>";

document.getElementById('newInvoice').onclick = function(){

   ...

      for (let i = 1; i <= productFields; i++) { 
      fields += field };

   ...
  };

每个组都需要自己的标识符。这样,您以后可以参考每行中的每个输入来计算子总价。该class属性是您可以分配给多个元素以便以后引用它们的东西。这class可以是任何东西,只要它不与class任何其他行的 相冲突。您可以使用i循环的作为您的标识符,因为它随着每个循环而变化。

     for (let i = 1; i <= productFields; i++) { 

       var field = "<label for='Item'>Item:</label> <input class='row-" + i + "' type=text name='item'>" +             
       "<label for='qty'> Qty: </label> <input class='row-" + i + "' type='number' name='qty'>" + 
       "<label for='Price'> Price ($):</label> <input class='row-" + i + "' type='number' name='price'> <br><br>";

      fields += field 
};

这会将类添加row-{i}到每一行中的每个字段。更好的是,您可以将其重构为自己的函数

function generateFields(i) {
       return "<label for='Item'>Item:</label> <input class='row-" + i + "' type=text name='item'>" +             
       "<label for='qty'> Qty: </label> <input class='row-" + i + "' type='number' name='qty'>" + 
       "<label for='Price'> Price ($):</label> <input class='row-" + i + "' type='number' name='price'> <br><br>";
}

     for (let i = 1; i <= productFields; i++) { 
        
      fields += generateFields(i);
};

您会得到类似于以下 html 的内容

    <label for='Item'>Item:</label> <input type=text class='row-1' name='item'>              
    <label for='qty'> Qty: </label> <input type='number' class='row-1' name='qty'> 
    <label for='Price'> Price ($):</label> <input type='number' class='row-1' name='price'> <br><br>

    <label for='Item'>Item:</label> <input type=text class='row-2' name='item'>              
    <label for='qty'> Qty: </label> <input type='number' class='row-2' name='qty'> 
    <label for='Price'> Price ($):</label> <input type='number' class='row-2' name='price'> <br><br>

    <label for='Item'>Item:</label> <input type=text class='row-3' name='item'>              
    <label for='qty'> Qty: </label> <input type='number' class='row-3' name='qty'> 
    <label for='Price'> Price ($):</label> <input type='number' class='row-3' name='price'> <br><br>

现在在您的计算函数中,您可以参考这些行并计算它们的价格。在这里,您可以遍历“项目”输入字段。


  document.getElementById('calculate').onclick = function getQtyFields() {
         let itemInputs= document.getElementsByName('item')

         for(let i = 0; i < itemInputs.length; i++){
           const identifier = itemInputs[i].className // get the class name of every item ex. 'row-1'

           const row = document.getElementsByClassName(identifier);
         }

     ...
 }

row现在是每行HTMLCollection包含item, qty, 和price的一个。您可以使用HTMLCollections其名称选择其任何元素.namedItem(<name>)

         for(let i = 0; i < itemInputs.length; i++){
           const identifier = itemInputs[i].className // get the class name of every item ex. 'row-1'

           const row = document.getElementsByClassName(identifier);  // ex. 'row-1'
           
           const qty = row.namedItem('qty').value;
           const basePrice = [YOUR BASE PRICE];

           const itemSubTotal = basePrice * qty; // heres is your item sub total!
         }

您现在可以将价格price插入该行的输入字段。


         for(let i = 0; i < itemInputs.length; i++){
           const identifier = itemInputs[i].className // get the class name of every item ex. 'row-1'

           const row = document.getElementsByClassName(identifier); // ex. 'row-1'
           
           const qty = row.namedItem('qty').value;
           const basePrice = [YOUR BASE PRICE];

           const itemSubTotal = basePrice * qty; // heres is your item sub total!

           const price = row.namedItem('price');
           price.value = itemSubTotal; // insert subtotal inside the price field
         }

现在,一旦您单击计算,您应该会看到总价和总数量的警报,并且应该会看到price填充了计算价格的输入字段。

这个解决方案非常基础,不应该引入任何你不知道的新概念。稍后在您的训练营中,您将了解可以使此类项目更易于管理和扩展的设计模式和框架。

如果遇到任何问题或有任何其他问题,请联系我!


推荐阅读