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
I think you should assign a variable to the table:
document. getElementById('I'd of table body');
To create the record build it as elements:
document.createElement('tr'), document.createElement('td'); Append to to tr. repeat as necessary...
Then append the new record element to the table body. Each element may be added to, such as adding attributes like class or events.
For this final record event add an on blur handler. document.addEventHandler('blur', function callback);
You can assign the element selector target in this case markup. You have to add the listener again after you create a new DOM element.
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>
There are several issues with your code
The two most important are
id
. But id
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 used name
instead of id
herefocusout
events. I listen to the focusout
event on the whole document. If you focus out of an input, the event will bubble up to the document
, where I decide, what to do based on the event's target
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>