附加的新行与前一行(行)的行为不同

IT技术 javascript jquery html-table
2021-03-22 09:29:50

我在一侧的HTML表,我有几个tdinput外地,我的表是动态的,当页面加载我正在追加我的表和第1行focus的第一个输入字段,在我的情况,即Item Name

我的行中有 3 个输入字段,它们是Item Name,Unit QtyDisc%

  • 当用户在ItemName输入字段内单击时,我正在从数据中搜索项目名称,该数据是数组内的对象以填充项目名称
  • 选择后,Item NAme我将焦点移至下一个输入字段,Unit Qty然后在该焦点移至下一个输入字段之后,该输入字段Disc%位于此之间,一些计算正在计算Total Amount
  • 然后在此之后,当用户从Disc%我附加新行中获得焦点时,实际上我有一个函数,其中我有代码来附加该行,所以我在焦点之外调用该函数Disc%
  • 焦点离开后,Disc%我希望我的焦点应该转到ItemName新行,并且应该表现得像它的行为(如从数据中搜索)等等

我对代码中的行进行了注释,以便用户更好地了解发生了什么

从我的角度来看,我认为我使用错误的方法来完成这项任务

注意:-将来在每个焦点上我可能会做一些计算,所以请以这种方式帮助我

我已经提供了所有信息,如果还不够,大家可以在评论中问我

编辑

根据从新行Wils's移出焦点后的答案,焦点Disc%也在转移到新行,Item Name但问题是当新行附加autocomplete时,当我在Item Name所有项目的输入字段中键入 m 时,页面加载时最初不在第一行中工作包含m名称显示为下拉列表,但第二行没有显示

任何人都在这里请帮助我

3个回答

您的代码有几个问题

最重要的两个是

  • 您使用多个具有相同id. ids 必须是唯一的。如果多个元素相同(CSS 不同),JavaScript/jQuery 将始终使用带有 id 的第一个元素。我用name而不是id这里
  • 您向元素添加事件侦听器,这些元素在运行时并不存在。当您侦听focusout事件时,只会创建第一个输入行focusout在整个文档中聆听事件。如果您不关注输入,则事件将冒泡到document,我决定根据事件的target属性在那里做什么

我对您的代码进行了一些重构并进行了一些改进,但它远非完美。

"use strict";
console.clear()


const data = [ //data to populate Item Name search input field
  {"ItemName": "Butter"},
  {"ItemName": "Rice"},
  {"ItemName": "Milk"},
  {"ItemName": "Ice Cream"},
  {"ItemName": "Curd"}
]

const data1 = {// this data will be dynamic but for now to test i am using this single data
  butter: { 
    "ItemName": "Butter",
    "ItemCode": 400564,
    "PurRate": 8,
    "DiscAmt": 6,
    "gstPercentage": 35,
    "gstAmt": 5
  },
  rice: { 
    "ItemName": "Rice",
    "ItemCode": 400565,
    "PurRate": 3,
    "DiscAmt": 2,
    "gstPercentage": 20,
    "gstAmt": 8
  },
  milk: { 
    "ItemName": "Milk",
    "ItemCode": 200569,
    "PurRate": 1,
    "DiscAmt": 1,
    "gstPercentage": 50,
    "gstAmt": 2
  },
  'ice cream': { 
    "ItemName": "Ice cream",
    "ItemCode": 800002,
    "PurRate": 16,
    "DiscAmt": 2,
    "gstPercentage": 15,
    "gstAmt": 2
  },
  curd: { 
    "ItemName": "Curd",
    "ItemCode": 100289,
    "PurRate": 9,
    "DiscAmt": 1,
    "gstPercentage": 12,
    "gstAmt": 4
  },
}

var totalAmount = "";
var unitQuantity = "";


function rowappend(tbody) {// this one is appending row{
  
  const markup = 
`<tr>
  <td>
    <input type="text" class="form-control commantd" name="itemNametd">
  </td>
  <td name="itemCodetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="unitQtytd">
  </td>
  <td name="purRatetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="discPercentagetd">
  </td>
  <td name="discAmttd" class="commantd"></td> 
  <td name="gstPercentagetd" class="commantd"></td>
  <td name="gstAmttd" class="commantd"></td>
  <td name="totalAmttd" class="commantd"></td>
  
</tr>`
    
  $(tbody).append(markup);
  setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

  const itemName = data.map(value => { //using autocomplete to for searching input field
    return value.ItemName;
  });
  $("[name=itemNametd]", tbody).last().autocomplete({
    source: itemName
  });
}
rowappend($('tbody', '#tableInvoice'))


function getValues(row) {
  const search = ($('[name=itemNametd]', row).val()).toString()
  const value = data1[search.toLowerCase()];
  if (value) {
    $(row).find("[name=itemCodetd]").text(value.ItemCode);
    $(row).find("[name=purRatetd]").text(value.PurRate);
    $(row).find("[name=discAmttd]").text(value.DiscAmt);
    $(row).find("[name=gstPercentahgetd]").text(value.gstPercentage);
    $(row).find("[name=gstAmttd]").text(value.gstAmt);
  }
}



function calc(row) {
  const unitQuantity = $(row).find("[name=unitQtytd]").val();
  const purchaseRate = $(row).find("[name=purRatetd]").text();
  const totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
  
  $(row).find("[name=totalAmttd]").text(totalAmount);
  
}

$(document).on('focusout', (e) => {
  const row = e.target.parentElement.parentElement
  if (e.target.matches('[name=discPercentagetd]')) {
    if ($(row).parent().find('tr').length - $(row).index() === 1) { // only last row
        rowappend(e.target.parentElement.parentElement.parentElement)
    }
  }
  
  if (e.target.matches('[name=unitQtytd]')) {
    calc(e.target.parentElement.parentElement)
  }

  if (e.target.matches("[name=itemNametd]")) {
    getValues(e.target.parentElement.parentElement)
  }

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet"/>

<div class="container commonDivInvoice">
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>
        </tr>
      </thead>
      <tbody>

      </tbody>

    </table>

  </div>
</div>

@dheerajkumar 这是一个新问题,您应该将其作为新问题发布。但首先你应该自己尝试。如果您认为您的问题已得到解答,请接受答案
2021-04-23 09:29:50
嘿,先生,我一直在关注您的代码结构,我做了很多事情,因为这里的表格在页面加载时填充并且itemName数据来自 JSON 所以我有一个单击下拉菜单我正在创建表格行,所以当我选择第一个选项,那里的数据在ItemName字段中作为自动完成,但是当我将其更改为选项 2 并加载其他数据时,它仍然只需要第一个数据,这仅用于选项一,如果您有一点时间,请帮我看看在这个小提琴jsfiddle.net/draj8126/hwvne90d/1
2021-05-03 09:29:50
先生,我已接受您的回答,但您可以进行一些编辑,这会有所帮助
2021-05-11 09:29:50
@dheerajkumar 我对您的代码进行了大量改进。现在轮到你尝试学习了
2021-05-14 09:29:50

在这种情况下,您可以分配元素选择器目标标记。创建新的 DOM 元素后,您必须再次添加侦听器。

因为你不能使用 id 两次......你必须使用类或输入字段数组。
2021-04-27 09:29:50
您应该将侦听器绑定到 body 而不是元素,以便您新创建的 DOM 对象可以执行操作。
2021-04-28 09:29:50
试试我的片段,我为你修好了。
2021-04-30 09:29:50
嘿,但是当我在Item Name自动完成中输入内容时,它不适用于新行
2021-05-13 09:29:50
这是我现在卡住的主要问题,当焦点从Disc%第 3 行移出后附加第 2 行没有附加
2021-05-21 09:29:50

我认为您应该为表分配一个变量:

文档。getElementById('我的表体');

要创建记录,请将其构建为元素:

document.createElement('tr'), document.createElement('td'); 附加到 tr。根据需要重复...

然后将新的记录元素附加到表体。可以添加每个元素,例如添加类或事件等属性。

对于这个最终记录事件,添加一个模糊处理程序。document.addEventHandler('blur', 函数回调);

因为我已经在我的帖子中写了所有的东西,当第一行的最后一列被聚焦时,我试图追加新行,并且在每个输入字段中,我正在计算一些值,一些计算正在进行,所以我想要一些代码形式的帮助
2021-05-20 09:29:50
Ddheeraj,当然我很乐意提供帮助并希望我早点看到这个。如果您仍然需要帮助,请告诉我。
2021-05-21 09:29:50