追加的新行的行为与上一行不同(行) [英] Appended new row is not behaving like previous one (row)
问题描述
我有一个HTML表,其中有几个td
作为input
字段,我的表是动态的,当页面加载时,我将表的第一行和focus
附加在第一个输入字段上,我的情况,即Item Name
I have a HTML table in side which i have several td
as input
field,my table is dynamic, when page loads i am appending the 1st row of my table and focus
on first input field, in my case i.e Item Name
我的行中有3个输入字段,分别是Item Name
,Unit Qty
和Disc%
I have 3 input fields in my row which are Item Name
,Unit Qty
and Disc%
- 当用户在
ItemName
输入字段中单击时,我正在从数据中搜索项目名称,该数据是用于填充项目名称的数组中的对象 - 选择
Item NAme
后,我将焦点移至下一个输入字段Unit Qty
,然后将焦点移至下一个输入字段中的Disc%
,在此之间进行了一些计算以计算Total Amount
- 然后在此之后,当用户从
Disc%
中移出焦点时,我要追加一个新行,实际上我有一个函数在其中,我有要附加该行的代码,因此我在Disc%
之外的焦点上调用了该函数 - 将焦点移出
Disc%
之后,我希望我的焦点移到新行的ItemName
上,并且应表现得像是在运行(就像从数据中搜索一样),依此类推
- When user clicks inside
ItemName
input field i am searching for itemnames from a data which is objects inside a array to populate itemnames - After selecting
Item NAme
i am moving my focus to next input field which isUnit Qty
then after that focus in to next input field which isDisc%
in between this some calculation are happening to calculateTotal Amount
- Then after this when user is focus out from
Disc%
i am appending a new row, actually i have a function inside which i have code to append the row, so i am calling that function on focus out ofDisc%
- After focus out of
Disc%
i want my focus should go to theItemName
of new row and should behave like it was behaving (Like search from data) and so on
我已在代码中注释了各行,以使用户更好地了解发生在哪里的情况
function rowappend() // this one is appending row
{
var markup = '<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
'</td><td id="itemCodetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
'<td id="purRatetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
'<td id="discAmttd" class="commantd"></td>' +
'<td id="gstPercentagetd" class="commantd"></td>' +
'<td id="gstAmttd" class="commantd"></td>' +
'<td id="totalAmttd" class="commantd"></td></tr>'
$("table tbody").append(markup);
$("itemNametd").next().focus();
}
rowappend()
var data = [ //data to populate Item Name search input field
{
"ItemName": "Butter"
},
{
"ItemName": "Rice"
},
{
"ItemName": "Milk"
},
{
"ItemName": "Ice Cream"
},
{
"ItemName": "Curd"
}
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
let itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("#itemNametd").autocomplete({
source: itemName
});
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this
data1.map(value => {
$("#itemCodetd").text(value.ItemCode);
$("#purRatetd").text(value.PurRate);
$("#discAmttd").text(value.DiscAmt);
$("#gstPercentahgetd").text(value.gstPercentage);
$("#gstAmttd").text(value.gstAmt);
});
});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
unitQuantity = $("#unitQtytd").val();
purchaseRate = $("#purRatetd").text();
totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$("#totalAmttd").text(totalAmount);
});
$("#discPercentagetd").focusout(function() { //here when user is focus out i am calling the fuinction which is creating new row
rowappend()
});
<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 rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<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>
从我的角度来看,我认为我使用错误的方法来完成此任务
From my side i think i am using wrong approach to do this task
注意:-,将来我可能会进行一些计算,因此请以这种方式帮助我
NOTE :- in future on each focus out i may be doing some calculations so please help me out in that way
我提供了所有信息,如果还不够的话,大家可以在评论中问我
I have provided all the information if it is not sufficient then you all can ask me in comments
编辑
在从Disc%
移出焦点后附加了新行,并且焦点也转移到了新行的Item Name
上,但是问题是当新行附加了autocomplete
时,它最初在第一行中不起作用当页面加载时,当我在Item Name
的输入字段内键入m时,所有包含m
的项目名称均显示为下拉列表,但第二行未显示
as per Wils's
answer after focus out from Disc%
new row is appending and focus is also shifting to new row's Item Name
but issue is when new row is appending the autocomplete
is not working in first row initially when page loads when i type m inside the input field of Item Name
all the item name containing m
are displayed as drop-down but for 2nd row its not showing up
function rowappend() // this one is appending row
{
var markup = $('<tr><td><input type="text" class="form-control commantd"name="itemNametd" id="itemNametd">' +
'</td><td id="itemCodetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="unitQtytd" id="unitQtytd"></td>' +
'<td id="purRatetd" class="commantd"></td>' +
'<td><input type="text" class="form-control commantd"name="discPercentagetd" id="discPercentagetd"></td>' +
'<td id="discAmttd" class="commantd"></td>' +
'<td id="gstPercentagetd" class="commantd"></td>' +
'<td id="gstAmttd" class="commantd"></td>' +
'<td id="totalAmttd" class="commantd"></td></tr>');
$("table tbody").append(markup);
$("#itemNametd", markup).focus();
}
rowappend()
var data = [ //data to populate Item Name search input field
{
"ItemName": "Butter"
},
{
"ItemName": "Rice"
},
{
"ItemName": "Milk"
},
{
"ItemName": "Ice Cream"
},
{
"ItemName": "Curd"
}
]
var data1 = [{ // this data will be dynamic but for now to test i am using this single data
"ItemName": "Butter",
"ItemCode": 400564,
"PurRate": 8,
"DiscAmt": 6,
"gstPercentage": 35,
"gstAmt": 5
}]
var totalAmount = "";
var unitQuantity = "";
$(function() {
let itemName = data.map(value => { //using autocomplete to for searching input field
return value.ItemName;
});
$("#itemNametd").autocomplete({
source: itemName
});
});
$("#itemNametd").focusout(function() { //when user focus out from Item Name doing this
data1.map(value => {
$("#itemCodetd").text(value.ItemCode);
$("#purRatetd").text(value.PurRate);
$("#discAmttd").text(value.DiscAmt);
$("#gstPercentahgetd").text(value.gstPercentage);
$("#gstAmttd").text(value.gstAmt);
});
});
$("#unitQtytd").focusout(function() { //when user focus out Unit Qty doing some calculation
unitQuantity = $("#unitQtytd").val();
purchaseRate = $("#purRatetd").text();
totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));
$("#totalAmttd").text(totalAmount);
});
$('body').on('focusout', '#discPercentagetd', function() {
rowappend()
});
<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 rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<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>
任何人在这里都请帮助我
Anyone out here please help me out
推荐答案
您的代码有几个问题
两个最重要的是
- 您可以使用多个具有相同
id
的元素.但是id
必须是唯一的.如果多个元素具有相同的元素(CSS不同),则JavaScript/jQuery将始终将第一个元素与id一起使用.我在这里使用name
而不是id
- 您将事件侦听器添加到元素,这些元素在运行时不存在.当您监听
focusout
事件时,仅创建第一个输入行.我听了整个文档中的focusout
事件.如果您将注意力集中在输入上,则事件将起泡至document
,我将根据事件的target
属性决定要执行的操作.
- You use multiple elements with the same
id
. Butid
s must be unique. JavaScript/jQuery will always use the first element with the id if multiple elements have the same (CSS is different). I usedname
instead ofid
here - You add event listeners to elements, which are not there at run-time. Only the first input-row is created, when you listen to the
focusout
events. I listen to thefocusout
event on the whole document. If you focus out of an input, the event will bubble up to thedocument
, where I decide, what to do based on the event'starget
property.
我对您的代码进行了一些重组,并进行了一些改进,但这远非完美.
I restructured your code a bit and made some improvements, but it's far from perfect.
"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>
这篇关于追加的新行的行为与上一行不同(行)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!