Jquery how to get change event in the element later loaded - javascript

The rows of my table are added dynamically and within each row possess a select option, I need to perform an action when the select is changed, but because the line is loaded after the page loaded, my function does not work.
<table id="grid-items" class="table table-bordered table-hover">
<thead>
<th>Cod</th>
<th>Desc</th>
<th>Uni</th>
<th>N.C.M.</th>
</thead>
<tr>
<td><input type="text" id="" class="form-control item-cod" required></input></td>
<td style="width:400px;"><select data-placeholder="Selecione" class="chosen-select item-descricao" style="width:350px;" tabindex="2" id=""></select></td>
<td><input type="text" id="" class="form-control item-ncm" required></input></td>
<td><button class="btn btn-default bg-red" onclick="RemoveTableRow(this)" type="button">Remover</button></td>
</tr>
<tfoot>
<tr>
<td colspan="5" style="text-align: left;">
<button class="btn btn-primary" onclick="AddTableRow()" type="button">Adicionar Item</button>
<td>
</tr>
</tfoot>
My function to add row
function AddTableRow() {
var newRow = $("<tr>");
var cols = "";
cols += '<td><input type="text" id="item-codigo" name="produto.itens[].codigo" class="form-control" required></input></td>';
cols += '<td style="width:400px;"><select data-placeholder="Selecione" class="chosen-select item-descricao" style="width:350px;" tabindex="2" id=""></select></td>';
cols += '<td><input type="text" id="item-ncm" name="produto.itens[].ncm" class="form-control" required></input></td>';
cols += '<td>';
cols += '<button class="btn btn-default bg-red" onclick="RemoveTableRow(this)" type="button">Remover</button>';
cols += '</td>';
newRow.append(cols);
$("#grid-items").append(newRow);
var options = '<option value="">Selecione</option>';
$.each(produtos, function (key, val){
options += '<option value="' + val.id + '">' + val.descricao + '</option>';
});
$("td .item-descricao").html(options);
var config = {
'.chosen-select' : {},
'.chosen-select-deselect' : {allow_single_deselect:true},
'.chosen-select-no-single' : {disable_search_threshold:10},
'.chosen-select-no-results': {no_results_text:'Oops, nothing found!'},
'.chosen-select-width' : {width:"95%"}
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
Whem change select:
$("td .item-descricao").on("change", function(e) {
var codigo = this.value;
$.each(produtos, function (key, val){
if( val.id == codigo){
$("td .item-codigo").val(val.id).trigger('change');
$("td .item-ncm").val(val.ncm).trigger('change');
}
});
});
which function could use to manipulate the dynamic selects? Tks.

You can delegate the event to a parent element:
$("parent-selector-goes-here").on("change", "child-selector-goes-here", function(e) {
// your code for the items' events
// here, "this" will be the event target element
};
In your case:
$("#grid-items").on("chage", "td .item-descricao", function(e) {
var codigo = this.value;
$.each(produtos, function (key, val) {
if (val.id == codigo) {
$("td .item-codigo").val(val.id).trigger('change');
$("td .item-ncm").val(val.ncm).trigger('change');
}
});
});
--
Boa sorte! ;)

Yes you're right, this line will take the currently matched elements and attach the change event:
$("td .item-descricao").on("change", function(e) { ... });
What you should use instead is attach the event handler on the document, and filter it to trigger the event only if it matches the CSS selector:
$(document).on("change", "td .item-descricao", function(e) {
var target = $(e.target);
// ...
});
The reason why this works is called "event bubbling": The change event will "bubble up" the DOM tree, so coming from the select all the way up to the html-Tag and above this, there is the document as parent of all tags.

Related

How to control dynamically added input type file?

I am trying to get the size of a dynamically added input type file.
JSP
<div>
<button type="button" id="appendTab" name="appendTab">Append</button>
<button type="button" id="deleteTab" name="deleteTab">Delete</button>
</div>
<table id="bnspTable" class="table">
<thead>
<tr>
<th style="width:8%;">check</th>
<th colspan="2" style="text-align:center; width:82%">FileName</th>
<th style="text-align:center; width:10%">FileSize</th>
</tr>
</thead>
<tbody id="fileTbody">
</tbody>
</table>
JS
$("#appendTab").on("click",function(){
page.appendTab();
})
page.appendTab = function(){
var cnt = $("#fileTbody tr").length + 1;
var addHtml = '<tr class="addFile" style="text-align:center;">';
addHtml += '<td><input type="checkbox" name="P_CHECK" style="width:25px; height:25px;"></td>';
addHtml += '<td colspan="2"><input type="text" name="uploadName" size="70" readonly><input type="file" id= "file_nm' +cnt+'" name="P_ORG_FILE_NM" class="fileNM" onchange="sizeCheck()"></td>';
addHtml += '<td><input type="text" name="fileSize" readonly size="10"></td>';
addHtml += '</tr>';
$("#bnspTable").find('tbody').append(addHtml);
}; //Ability to add rows to tbody
sizeCheck = function(){
$(document).on('change','.fileNM',(function(){
var file = this.files[0];
var fileName = file.name;
var fileSize = file.size;
$("input[name='fileSize']").val(fileSize);
}));
/*
At first,i can do it by giving a class, but it will be overwritten with the file size added
later.*/
};
At first,i can do it by giving a class, but it will be overwritten with the file size added
later.
I'm trying to control by id, but it's not working, so I'm going to do it by name.
When i add a file, i want to put the size of the file into input with name = "fileSize"
However, I don't know how many files will be added, so I can't figure out what to do.
There's two main issues here. Firstly as you're correctly using a delegated event handler here you only need to instantiate it once, not within the sizeCheck() function. Doing that will mean the handler is bound multiple times which is the last thing you need. Therefore move the on() call outside of that function and remove onclick from your HTML.
The second issue is that you're selecting all input[name='fileSize'] elements in the change handler, whereas you only need to find the one related to the file input which triggered the event. To do that use jQuery's DOM traversal methods, closest() and find() in this case.
With all that said, try this:
let page = {};
page.appendTab = function() {
var addHtml = '<tr class="addFile">';
addHtml += '<td><input type="checkbox" name="P_CHECK"></td>';
addHtml += '<td colspan="2"><input type="text" name="uploadName" size="70" readonly><input type="file" name="P_ORG_FILE_NM" class="fileNM"></td>';
addHtml += '<td><input type="text" name="fileSize" readonly size="10"></td>';
addHtml += '</tr>';
$("#bnspTable").find('tbody').append(addHtml);
};
$("#appendTab").on("click", function() {
page.appendTab();
})
$(document).on('change', '.fileNM', (function() {
var file = this.files[0];
var fileName = file.name;
var fileSize = file.size;
$(this).closest('tr').find('input[name="fileSize"]').val(fileSize);
}));
.addFile {
text-align: center;
}
.addFile input[type="checkbox"] {
width: 25px;
height: 25px;
}
tr th:nth-child(1) {
width: 8%;
}
tr th:nth-child(2) {
text-align: center;
width: 82%
}
tr th:nth-child(3) {
text-align: center;
width: 10%
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button type="button" id="appendTab" name="appendTab">Append</button>
<button type="button" id="deleteTab" name="deleteTab">Delete</button>
</div>
<table id="bnspTable" class="table">
<thead>
<tr>
<th>check</th>
<th colspan="2">FileName</th>
<th>FileSize</th>
</tr>
</thead>
<tbody id="fileTbody"></tbody>
</table>
As an aside, don't use incremental id attributes. It's an anti-pattern as it creates more complex and verbose code which is harder to maintain. You don't need them at all anyway when using DOM traversal correctly. In addition, don't use inline style attributes. Put all style rules in an external stylesheet.
you can probably bind an event after adding html in to DOM.
below is updated code.
var page={}
$("#appendTab").on("click",function(){
page.appendTab();
})
page.appendTab = function(){
var cnt = $("#fileTbody tr").length + 1;
var addHtml = '<tr class="addFile" style="text-align:center;">';
addHtml += '<td><input type="checkbox" name="P_CHECK" style="width:15px; height:15px;"></td>';
addHtml += '<td colspan="2"><input type="text" name="uploadName" style="width:100px;" id="file_' +cnt+'" size="70" readonly><input type="file" id= "file_nm' +cnt+'" name="P_ORG_FILE_NM" class="fileNM"></td>';
addHtml += '<td><input type="text" name="fileSize" readonly size="10" id="size_inpt' +cnt+'"></td>';
addHtml += '</tr>';
$("#bnspTable").find('tbody').append(addHtml);
$("#file_nm" +cnt).on("change",function(){
debugger
var file = this.files[0];
var fileName = file.name;
var fileSize = file.size;
$("#size_inpt"+cnt).val(fileSize);
$("#file_" +cnt).val(fileName)
})
}; //Ability to add rows to tbody
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<button type="button" id="appendTab" name="appendTab">Append</button>
<button type="button" id="deleteTab" name="deleteTab">Delete</button>
</div>
<table id="bnspTable" class="table">
<thead>
<tr>
<th style="width:8%;">check</th>
<th colspan="2" style="text-align:center; width:82%">FileName</th>
<th style="text-align:center; width:10%">FileSize</th>
</tr>
</thead>
<tbody id="fileTbody">
</tbody>
</table>

How to copy the value from one input box to another input box?

By clicking on Add New Row button, new input boxes can be generated. I want to copy the value from one input box (First column - Hours ) to another input box (Second Column - In Office).
Screenshot:
First Row: Value is copied from one input box to another input box when it is a static element. Here input box is created by HTML.
Dynamic Rows: Value is not copied from one input box to another input box when it is a dynamic element. Here input box is created by JavaScript.
Issue:
Value is not copied because the elements are generated dynamically with same id and name
What I tried:
$(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
var actions = $("table td:last-child").html();
// Append table with add row form on add new button click
$(".add_new").click(function() {
var index = $("table tbody tr:last-child").index();
var row = '<tr>' +
'<td><input type="number" name="hours[]" id="hours"></td>' +
'<td><input type="number" name="inoffice[]" id="inoffice"></td>' +
'</tr>';
$("table").append(row);
$('[data-toggle="tooltip"]').tooltip();
});
// Add row on add button click
$(document).on("click", ".add", function() {
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function() {
if (!$(this).val()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function() {
$(this).parent("td").html($(this).val());
});
}
});
});
function sync() {
var hours = document.getElementById('hours');
var inoffice = document.getElementById('inoffice');
inoffice.value = hours.value;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<table class="table table-bordered">
<thead>
<tr>
<th>Hours</th>
<th>In Office</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="hours[]" id="hours" onkeyup="sync()" onClick="sync()"></td>
<td><input type="number" name="inoffice[]" id="inoffice"></td>
</tr>
</tbody>
</table>
<input type="button" id="add_new" name="add_new" class="add_new" value="Add New Row">
You should not be duplicating id attributes as it's invalid HTML and will lead to other issues. Use class attributes instead to group elements by common behaviour patterns.
From there you can use a delegated event handler to handle all the .hours elements that will ever exist in the DOM.
Also note that inline event attributes are outdated and should be avoided where possible.
$('table').on('input', '.hours', function() {
$(this).closest('tr').find('.inoffice').val(this.value);
});
$(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
var actions = $("table td:last-child").html();
$(".add_new").click(function() {
var index = $("table tbody tr:last-child").index();
var row = '<tr>' +
'<td><input type="number" name="hours[]" class="hours"></td>' +
'<td><input type="number" name="inoffice[]" class="inoffice"></td>' +
'</tr>';
$("table").append(row);
$('[data-toggle="tooltip"]').tooltip();
});
$(document).on("click", ".add", function() {
var empty = false;
var input = $(this).parents("tr").find('input[type="text"]');
input.each(function() {
if (!$(this).val()) {
$(this).addClass("error");
empty = true;
} else {
$(this).removeClass("error");
}
});
$(this).parents("tr").find(".error").first().focus();
if (!empty) {
input.each(function() {
$(this).parent("td").html($(this).val());
});
}
});
$('table').on('input', '.hours', function() {
$(this).closest('tr').find('.inoffice').val(this.value);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<table class="table table-bordered">
<thead>
<tr>
<th>Hours</th>
<th>In Office</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="hours[]" class="hours"></td>
<td><input type="number" name="inoffice[]" class="inoffice"></td>
</tr>
</tbody>
</table>
<input type="button" id="add_new" name="add_new" class="add_new" value="Add New Row">
Start by creating an MCVE. That means remove all the code that isn't part of the problem. This will make everything clearer.
Remove IDs, since IDs must be unique, we better use classes instead.
$(document).ready(function() {
$(".add_new").click(function() {
var index = $("table tbody tr:last-child").index();
var row = '<tr>' +
'<td><input type="number" name="hours[]" class="hours"></td>' +
'<td><input type="number" name="inoffice[]" class="inoffice"></td>' +
'</tr>';
$("table").append(row);
$('[data-toggle="tooltip"]').tooltip();
});
});
$(document).on("keyup", ".hours", function(){
$(this).parent().parent().find(".inoffice").val(this.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<table class="table table-bordered">
<thead>
<tr>
<th>Hours</th>
<th>In Office</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" name="hours[]" class="hours"></td>
<td><input type="number" name="inoffice[]" class="inoffice"></td>
</tr>
</tbody>
</table>
<input type="button" id="add_new" name="add_new" class="add_new" value="Add New Row">

jQuery dynamic content calculate

My code is working perfectly with static part, but when i add a new row it won't calculate the field. What am i doing wrong?
It should calculate also the dynamic fields which are added via Add Row button
Live DEMO
<div class="container">
<table id="t1" class="table table-hover">
<tr>
<th class="text-center">Start Time</th>
<th class="text-center">End Time</th>
<th class="text-center">Stunden</th>
<th> <button type="button" class="addRow">Add Row</button></th>
</tr>
<tr id="row1" class="item">
<td><input name="starts[]" class="starts form-control" ></td>
<td><input name="ends[]" class="ends form-control" ></td>
<td><input name="stunden[]" class="stunden form-control" readonly="readonly" ></td>
</tr>
</table>
</div>
js
$(document).ready(function(){
$('.item').keyup(function(){
var starts = $(this).find(".starts").val();
var ends = $(this).find(".ends").val();
var stunden;
s = starts.split(':');
e = ends.split(':');
min = e[1]-s[1];
hour_carry = 0;
if(min < 0){
min += 60;
hour_carry += 1;
}
hour = e[0]-s[0]-hour_carry;
min = ((min/60)*100).toString()
stunden = hour + "." + min.substring(0,2);
$(this).find(".stunden").val(stunden);
});
// function for adding a new row
var r = 1;
$('.addRow').click(function () {
if(r<10){
r++;
$('#t1').append('<tr id="row'+ r +'" class="item"><td><input name="starts[]" class="starts form-control" ></td><td><input name="ends[]" class="ends form-control" ></td><td><input name="stunden[]" class="stunden form-control" readonly="readonly" ></td></tr>');
}
});
// remove row when X is clicked
$(document).on("click", ".btn_remove", function () {
r--;
var button_id = $(this).attr("id");
$("#row" + button_id + '').remove();
});
});
The best thing would be to use the .on() event which is used to attach one or more event handlers to the element:
$(document).on('keyup', '.item',function(){
//your code
}
When you dynamically add a new row to your table, the "keyup" event wont automatically be bound to it. Essentially you need to wrap the "keyup" event binding into a function, then call it after you've added the new row on. Something along the lines of:
function rebindKeyup(){
$('.item').keyup(function(){
// Key up logic
}
}

Jquery Event Not Triggering for DOM Elements Created after page load [duplicate]

This question already has answers here:
jQuery doesn't work after content is loaded via AJAX
(9 answers)
Closed 8 years ago.
I have a page that trigger a calculate() function when a html5 number field is changed I have bound just about every event I can think of to it and it works for the originally loaded DOM elements.
However, if I add elements after the dom is loaded the change functions do not trigger.
I added a button that runs the calculate() function and when click it will run for the newly created elements as well as the original ones.
So I know the code works but the event isn't firing for the newly created dom elements.
Jquery Triggers
$('.score').change(function() {
calculate();
});
$('.score').bind('keyup mouseup', function() {
calculate();
});
$('.score').mousewheel(function() {
calculate();
});
$('.score').click(function() {
calculate();
});
$('.score').keypress(function() {
calculate();
});
Calculate Function
function calculate() {
$("tbody tr").each(function() {
row_total = 0;
$(".score", this).each(function() {
row_total += Number($(this).val());
});
$(".total", this).val(row_total);
});
var arr = [];
var row = 0;
$("tbody tr").each(function() {
$(".total", this).each(function() {
arr[row] = $(this).val();
row += 1;
});
});
var sorted = arr.slice().sort(function(a, b) {
return b - a
})
var ranks = arr.slice().map(function(v) {
return sorted.indexOf(v) + 1
});
row = 0;
$("tbody tr").each(function() {
$(".place", this).each(function() {
$(this).val(ranks[row]);
row += 1;
});
});
$("tbody tr").each(function() {
$(".place", this).each(function() {
var p = $(this).val();
switch (p) {
case '1':
$(this).css('background-color', 'gold');
break;
case '2':
$(this).css('background-color', 'silver');
break;
case '3':
$(this).css('background-color', '#8c7853');
break;
case '4':
$(this).css('background-color', 'white');
break;
default:
$(this).css('background-color', 'white');
}
});
});
}
genRow Function
function genRow(i)
{
var x = "";
for (var j = 0; j < i; j++) {
x += '<tr class="competitors">';
x += '<td class="row">';
x += '<input class="name" type="text" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="score" type="number" step="1" min="-100" max="100" value="0" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="score" type="number" step="1" min="-100" max="100" value="0" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="score" type="number" step="1" min="-100" max="100" value="0" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="score" type="number" step="1" min="-100" max="100" value="0" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="score" type="number" step="1" min="-100" max="100" value="0" />';
x += '</td>';
x += '<td class="row">';
x += '<input class="total" type="text" value="0"/>';
x += '</td>';
x += '<td class="row">';
x += '<input class="place" type="text" value="0"/>';
x += '</td>';
x += '</tr>';
}
return x;
}
HTML Code
<body>
<table id="main">
<tr>
<td class="header">
Name
</td>
<td class="header judge">
Judge 1
</td>
<td class="header judge">
Judge 2
</td>
<td class="header judge">
Judge 3
</td>
<td class="header judge">
Judge 4
</td>
<td class="header judge">
Judge 5
</td>
<td class="header btn">
<input id="btn_Total" type="button" value="Total"/>
</td>
<td class="header h_place">
Place
</td>
</tr>
<tr class="competitors">
</tr>
<tr>
<td colspan="7"></td>
<td class="header btn">
<input id="btn_AddRow" type="button" value="Add Row"/>
</td>
</tr>
</table>
</body>
Currently what you are using is called a direct binding which will only attach to element that exist on the page at the time your code makes the event binding call.
You need to use Event Delegation using .on() delegated-events approach, when generating elements dynamically or manipulation selector (like removing and adding classes).
i.e.
$(document).on('event','selector',callback_function)
Example
$(document).on('click', '.score', function(){
//Your code
alert("clicked me");
});
In place of document you should use closest static container.
The delegated events have the advantage that they can process events from descendant elements that are added to the document at a later time. By picking an element that is guaranteed to be present at the time the delegated event handler is attached, we can use delegated events to bind the click event to dynamically created elements and also to avoid the need to frequently attach and remove event handlers.

jQuery not working on added rows [duplicate]

This question already has answers here:
Event handler not working on dynamic content [duplicate]
(2 answers)
Closed 9 years ago.
I have a table to allow user to do multiple stock entry
<table class="table1" id="table1">
<thread>
<tr>
<th scope="col">Item Name</th>
<th scope="col">Qty</th>
<th scope="col">Rate</th>
<th scope="col">Amount</th>
</tr>
</thread>
<tbody>
<tr>
<td><input type="text"/></td>
<td><input type="text" class="num" id="qty"/></td>
<td><input type="text" class="num" id="rate"/></td>
<td><input type="text" class="num" id="amt"/></td>
</tr>
</tbody>
</table>
<a id="add"><button>Add</button></a>
And this code is to add a new row:
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function() {
var newrow = $("<tr><td><input type="text"/></td><td><input type=\"text\" id=\"qty\"/></td><td><input type="\text\" id="\rate\"/></td><td><input type="\text\" id="\amt\"/></td></tr>");
newrow.insertAfter('#table1 tbody>tr:last');
return false;
});
$(".num").keyup(function() {
var id = $(this).attr('id');
if (id == 'qty') {
var i = parseFloat($("#rate").val())
if (!isNaN(i)) {
var t = ($(this).val()*$("#rate").val());
$("#amt").val(t.toFixed(2));
} else {
$("#amt").val('');
}
} else if (id == 'rate') {
var i = parseFloat($("#qty").val())
if (!isNaN(i)) {
var t = ($(this).val()*$("#qty").val());
$("#amt").val(t.toFixed(2));
} else {
$("#amt").val('');
}
}
});
});
The calculation is working perfect on the first row of table, but when I am adding a second row the calculation is not working. Where I am wrong?
Use event delegation:
$('body').on('keyup', ".num", function() {
// your code
});
Also you must add class .num to your created elements,
and you can't have the same ID for multiple elements, instead
use another attribute (like data-id, it doesn't matter),
var newrow = $('<tr><td><input type="text" /></td><td><input type="text" class="num" data-id="qty"/></td><td><input type="text" data-id="rate"/></td><td><input type="text" class="num" data-id="amt" /></td></tr>');
And in your function get them with this attribute:
$('body').on('keyup', ".num", function() {
var $row = $(this).closest('tr');
var $amt = $row.find('[data-id="amt"]');
var $qty = $row.find('[data-id="qty"]');
var $rate = $row.find('[data-id="rate"]');
var id = $(this).attr('data-id');
if (id == 'qty') {
// now using `$rate` instead of $('#rate')
var i = parseFloat($rate.val())
// other code
}
// other code
});
Give the new rows the num class (your new inputs don't have it), and use .on:
$(document).on('keyup', '.num', function() {
});
This is required if you want to add an event listener to elements that are not yet in the DOM.
Also, element IDs should be unique. Your new inputs are getting the same ID as the previous row.
try this
<table class="table1" id="table1">
<thread>
<tr>
<th scope="col">Item Name</th>
<th scope="col">Qty</th>
<th scope="col">Rate</th>
<th scope="col">Amount</th>
</tr>
</thread>
<tbody>
<tr>
<td>
<input type="text" />
</td>
<td>
<input type="text" class="num" name="qty" id="qty" />
</td>
<td>
<input type="text" class="num" id="rate" name="rate" />
</td>
<td>
<input type="text" class="num" id="amt" name="amt" />
</td>
</tr>
</tbody>
</table>
<a id="add">
<button>
Add</button></a>
<script type="text/javascript">
$(document).ready(function () {
$("#add").click(function () {
var newrow = $('<tr><td><input type="text"></td><td><input type="text" id="qty" name="qty" class="num"></td><td><input type="text" id="rate" name="rate" class="num"></td><td><input type="text" id="amt" name="amt" class="num"></td></tr>');
newrow.insertAfter('#table1 tbody>tr:last');
$('#table1 tbody>tr:last').find('[name="qty"]').keyup(function () {
var this_tr = $(this).closest('tr');
;
var i = parseFloat(this_tr.find('[name="rate"]').val())
if (!isNaN(i)) {
var t = ($(this).val() * this_tr.find('[name="rate"]').val());
this_tr.find('[name="amt"]').val(t.toFixed(2));
} else {
this_tr.find('[name="amt"]').val('');
}
});
$('#table1 tbody>tr:last').find('[name="rate"]').keyup(function () {
var this_tr = $(this).closest('tr');
;
var i = parseFloat(this_tr.find('[name="qty"]').val())
if (!isNaN(i)) {
var t = ($(this).val() * this_tr.find('[name="qty"]').val());
this_tr.find('[name="amt"]').val(t.toFixed(2));
} else {
this_tr.find('[name="amt"]').val('');
}
});
return false;
});
$('[name="qty"]').keyup(function () {
var this_tr = $(this).closest('tr');
;
var i = parseFloat(this_tr.find('[name="rate"]').val())
if (!isNaN(i)) {
var t = ($(this).val() * this_tr.find('[name="rate"]').val());
this_tr.find('[name="amt"]').val(t.toFixed(2));
} else {
this_tr.find('[name="amt"]').val('');
}
});
$('[name="rate"]').keyup(function () {
var this_tr = $(this).closest('tr');
;
var i = parseFloat(this_tr.find('[name="qty"]').val())
if (!isNaN(i)) {
var t = ($(this).val() * this_tr.find('[name="qty"]').val());
this_tr.find('[name="amt"]').val(t.toFixed(2));
} else {
this_tr.find('[name="amt"]').val('');
}
});
});
</script>
This issue can be solved via event delegation to the existing closet parent like in your case is $('#table1') or $(document) which is the parent of all the elements on a page, so you need to change this:
$(".num").keyup(function() {
to this:
$("#table").on('keyup', '.num', function() {
I just seen your additions you are adding same ids when clicked to add, so that results in a invalid html markup due to ids should be unique in the same page (same ids for multiple elems is invalid).
var newrow = $("<tr><td><input type='text'/></td>"+
"<td><input type='text' id='qty'/></td>"+
"<td><input type='text' id='rate'/></td>"+
"<td><input type='text' id='amt'/></td></tr>");
The above one everytime adds same id for multiple elements when added to the dom. you can try to do this way:
$("#add").click(function () {
var i = $("#table1 tbody>tr:last").index();
var newrow = $("<tr><td><input type='text'/></td>" +
"<td><input type='text' class='num' id='qty" + (i) + "'/></td>" +
"<td><input type='text' class='num' id='rate" + (i) + "'/></td>" +
"<td><input type='text' class='num' id='amt" + (i) + "'/></td>");
newrow.insertAfter('#table1 tbody>tr:last');
return false;
});

Categories

Resources