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;
});
Related
I'm trying to apply a function to input field with ids that contain consequent numbers (ie. price1, price2, price3), etc.
There's no problem with the first row of field that are defined for a start. But further input fields are dynamically added by a jQuery function and their number is not known in advance.
I hoped it would be an easy loop to apply:
var i=1;
$("#quantity"+i).keyup(function() {
var price= $("#price"+i).val();
var quantity= $(this).val();
var value= price*quantity;
var value=value.toFixed(2); /* rounding the value to two digits after period */
value=value.toString().replace(/\./g, ',') /* converting periods to commas */
$("#value"+i).val(value);
});
So far so good - the outcome of the multiplication properly displays in the id="value1" field after the "quantity" field is filled up.
Now further fields should follow the pattern and calculate the value when the quantity is entered - like this:
[price2] * [quantity2] = [value2]
[price3] * [quantity3] = [value3]
etc.
So the code follows:
$('#add_field').click(function(){ /* do the math after another row of fields is added */
var allfields=$('[id^="quantity"]');
var limit=(allfields.length); /* count all fields where id starts with "quantity" - for the loop */
for (var count = 2; count < limit; count++) { /* starting value is now 2 */
$("#quantity"+count).keyup(function() {
var cena = $("#price"+count).val();
var quantity= $("#quantity"+count).val();
var value= price*quantity;
var value=value.toFixed(2);
value=value.toString().replace(/\./g, ',')
$("#value"+count).val(value);
});
}
});
The problem is that all further "value" fields are only calculated when "quantity2" is (re)entered and the "value2" is not calculated at all.
I guess there's a mistake while addressing fields and/or triggering the calculation.
How should I correct the code?
Just in case the "add_field" function is needed to solve the problem:
$(document).ready(function(){
var i=1;
$('#add_field').click(function(){
i++;
$('#offer').append('<tr id="row'+i+'">
<td><input type="text" name="prod_num[]" id="prod_num'+i+'" placeholder="Product number (6 digits)"></td><td><input type="text" name="prod_name[]" disabled></td>
<td><input type="text" name="cena[]" id="price'+i+'" placeholder="Enter your price"></td>
<td><input type="text" name="quantity[]" id="quantity'+i+'" placeholder="Enter quantity"></td>
<td><input type="text" name="value[]" id="value'+i+'" disabled></td>
<td><button type="button" name="remove_field" id="'+i+'" class="button_remove">X</button></td></tr>');
});
Incrementing IDs is a lot more trouble than it is worth, especially when you start removing rows as well as adding them.
This can all be done using common classes and traversing within the specific row instance.
To account for future rows use event delegation.
Simplified example:
// store a row copy on page load
const $storedRow = $('#myTable tr').first().clone()
// delegate event listener to permanent ancestor
$('#myTable').on('input', '.qty, .price', function(){
const $row = $(this).closest('tr'),
price = $row.find('.price').val(),
qty = $row.find('.qty').val();
$row.find('.total').val(price*qty)
});
$('button').click(function(){
// insert a copy of the stored row
// delegated events will work seamlessly on new rows also
const $newRow = $storedRow.clone();
const prodName = 'Product XYZ';// get real value from user input
$newRow.find('.prod-name').text(prodName)//
$('#myTable').append($newRow)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>Add row</button>
<table id="myTable">
<tr>
<td class="prod-name">Product 1</td>
<td>Qty:<input type="number" class="qty" value="0"></td>
<td>Price:<input type="number" class="price" value="0"></td>
<td>Total:<input type="text" class="total" value="0" readonly></td>
</tr>
<tr>
<td class="prod-name">Product 2</td>
<td>Qty:<input type="number" class="qty" value="0"></td>
<td>Price:<input type="number" class="price" value="0"></td>
<td>Total:<input type="text" class="total" value="0" readonly></td>
</tr>
</table>
Understanding Event Delegation
The first thing to consider is that you can get the length of a selector. So for example:
var count = $("input").length;
If there is one, value here would be 1. if there are four, the value would be 4.
You can also use .each() option to itereate each of the items in the selector.
$('#add_field').click(function(){
var allFields = $('[id^="quantity"]');
allFields.each(function(i, el){
var c = i + 1;
$(el).keyup(function() {
var price = parseFloat($("#price" + c).val());
var quantity = parseInt($(el).val());
var value = price * quantity;
value = value.toFixed(2);
value = value.toString().replace(/\./g, ',');
$("#value" + c).val(value);
});
});
});
You could also create relationship based on the ID itself.
$(function() {
function calcTotal(price, qnty) {
return (parseFloat(price) * parseInt(qnty)).toFixed(2);
}
$('#add_field').click(function() {
var rowClone = $("#row-1").clone(true);
var c = $("tbody tr[id^='row']").length + 1;
rowClone.attr("id", "row-" + c);
$("input:eq(0)", rowClone).val("").attr("id", "prod_num-" + c);
$("input:eq(1)", rowClone).val("").attr("id", "price-" + c);
$("input:eq(2)", rowClone).val("").attr("id", "quantity-" + c);
$("input:eq(3)", rowClone).val("").attr("id", "value-" + c);
$("button", rowClone).attr("id", "remove-" + c);
rowClone.appendTo("table tbody");
});
$("table tbody").on("keyup", "[id^='quantity']", function(e) {
var $self = $(this);
var id = $self.attr("id").substr(-1);
if ($("#price-" + id).val() != "" && $self.val() != "") {
$("#value-" + id).val(calcTotal($("#price-" + id).val(), $self.val()));
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="add_field">Add Field</button>
<br />
<h2>Product</h2>
<table>
<thead>
<tr>
<td>Number</td>
<td>Name</td>
<td>Price</td>
<td>Quantity</td>
<td>Total</td>
<td></td>
</thead>
<tbody>
<tr id="row-1">
<td><input type="text" name="prod_num[]" id="prod_num-1" placeholder="Product number (6 digits)"></td>
<td><input type="text" name="prod_name[]" disabled></td>
<td><input type="text" name="cena[]" id="price-1" placeholder="Enter your price"></td>
<td><input type="text" name="quantity[]" id="quantity-1" placeholder="Enter quantity"></td>
<td><input type="text" name="value[]" id="value-1" disabled></td>
<td><button type="button" name="remove_field" id="remove-1" class="button_remove">X</button></td>
</tr>
</tbody>
</table>
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">
I have a table where the user can decide how many rows they wish to add. I've found a script that copy and pastes both columns and rows from excel. It works perfectly from the first 2 existing row's but the function doesn't work properly in any of the cloned rows that get added.
So if you use the function on the first two row's it will split the paste into each row and column (inluding the cloned rows) but if i try paste into a newly added row the function just doesn't work,
function cloneRow() {
var rowAmmount = document.getElementById("rowAmmount").value;
var getTotalRows = $('table > tbody').children().length;
for (var i = -1; i < rowAmmount-1;i++) {
var row = document.getElementById("row"); // find row to copy
var table = document.getElementById("table"); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "newRow" + (getTotalRows + i); // change id or other attributes/contents
clone.classList.remove('hidden');
table.appendChild(clone); // add new row to end of table
$('#newRow' + (getTotalRows + i)).children().each(function() {
$(this).children().attr('id', $(this).children().attr('id') + (getTotalRows + i));
});
}}
$('input').on('paste', function(e){
var $this = $(this);
$.each(e.originalEvent.clipboardData.items, function(i, v){
if (v.type === 'text/plain'){
v.getAsString(function(text){
var x = $this.closest('td').index(),
y = $this.closest('tr').index()+1,
obj = {};
text = text.trim('\r\n');
$.each(text.split('\r\n'), function(i2, v2){
$.each(v2.split('\t'), function(i3, v3){
var row = y+i2, col = x+i3;
obj['cell-'+row+'-'+col] = v3;
$this.closest('table').find('tr:eq('+row+') td:eq('+col+') input').val(v3);
});
});
});
}
});
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="rowAmmount"/>
<button id="add" onclick="cloneRow()">New Row</button>
<button type="button" onclick="submit()">Submit</button>
<table>
<thead>
<tr>
<th>Product Code</th>
<th>Item Name</th>
<th>Long Description></th>
<th>Material</th>
<th>Style</th>
</tr>
</thead>
<tbody id="table">
<tr id="row">
<td><input id="productId"></td>
<td><input id="itemname"></td>
<td><input id="long"></td>
<td><input id="fabric"></td>
<td><input id="style"></td>
</tr>
<tr id= "newRow0">
<td><input id="productId0"></td>
<td><input id="itemname0"></td>
<td><input id="long0"></td>
<td><input id="fabric0"></td>
<td><input id="style0"></td>
</tr>
</tbody>
</table>
You attach the change event handler before you insert the new inputs.
What you need is delegated event handling $('table').on('paste', 'input', function(e){
function cloneRow() {
var rowAmmount = document.getElementById("rowAmmount").value;
var getTotalRows = $('table > tbody').children().length;
for (var i = -1; i < rowAmmount-1;i++) {
var row = document.getElementById("row"); // find row to copy
var table = document.getElementById("table"); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "newRow" + (getTotalRows + i); // change id or other attributes/contents
clone.classList.remove('hidden');
table.appendChild(clone); // add new row to end of table
$('#newRow' + (getTotalRows + i)).children().each(function() {
$(this).children().attr('id', $(this).children().attr('id') + (getTotalRows + i));
});
}}
$('table').on('paste', 'input', function(e){
var $this = $(this);
$.each(e.originalEvent.clipboardData.items, function(i, v){
if (v.type === 'text/plain'){
v.getAsString(function(text){
var x = $this.closest('td').index(),
y = $this.closest('tr').index()+1,
obj = {};
text = text.trim('\r\n');
$.each(text.split('\r\n'), function(i2, v2){
$.each(v2.split('\t'), function(i3, v3){
var row = y+i2, col = x+i3;
obj['cell-'+row+'-'+col] = v3;
$this.closest('table').find('tr:eq('+row+') td:eq('+col+') input').val(v3);
});
});
});
}
});
return false;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="rowAmmount"/>
<button id="add" onclick="cloneRow()">New Row</button>
<button type="button" onclick="submit()">Submit</button>
<table>
<thead>
<tr>
<th>Product Code</th>
<th>Item Name</th>
<th>Long Description></th>
<th>Material</th>
<th>Style</th>
</tr>
</thead>
<tbody id="table">
<tr id="row">
<td><input id="productId"></td>
<td><input id="itemname"></td>
<td><input id="long"></td>
<td><input id="fabric"></td>
<td><input id="style"></td>
</tr>
<tr id= "newRow0">
<td><input id="productId0"></td>
<td><input id="itemname0"></td>
<td><input id="long0"></td>
<td><input id="fabric0"></td>
<td><input id="style0"></td>
</tr>
</tbody>
</table>
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.
I have this html table:
<table id='table1'>
<tr>
<td>String</td>
<td><input type='text' id='first-input-01'></input></td>
<td><input type='text' id='second-input-01'></input></td>
</tr>
<tr>
<td>String</td>
<td><input type='text' id='first-input-02'></input></td>
<td><input type='text' id='second-input-02'></input></td>
</tr>
<tr>
<td>Total:</td>
<td> </td>
<td>(total goes here)</td>
</tr>
</table>
and using jQuery, I want to find the value of #first-input-xx and multiply it by #second-input-xx for each table row, adding up each row to an overall total. However, I'm finding it difficult to select each input for each table row. I'm trying:
var total = 0;
$("#table1 tr").each(function() {
var amount1 = $(this).children("td:nth-last-child(2) input").val();
var amount2 = $(this).children("td:last input").val();
total = total + (parseFloat(amount1) * parseFloat(amount2));
});
Appreciative of any help.
You cannot use .children() as you are trying to find the input element, instead use .find()
var total = 0;
$("#table1 tr").each(function () {
var amount1 = $(this).find("td:eq(-2) input").val();
var amount2 = $(this).find("td:last input").val();
total += (parseFloat(amount1) * parseFloat(amount2)) || 0;
});
alert(total)
$('button').click(function() {
var total = 0;
$("#table1 tr").each(function() {
var amount1 = $(this).find("td:eq(-2) input").val();
var amount2 = $(this).find("td:last input").val();
total += (parseFloat(amount1) * parseFloat(amount2)) || 0;
});
alert(total)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id='table1'>
<tr>
<td>String</td>
<td>
<input type='text' id='first-input-01'></input>
</td>
<td>
<input type='text' id='second-input-01'></input>
</td>
</tr>
<tr>
<td>String</td>
<td>
<input type='text' id='first-input-02'></input>
</td>
<td>
<input type='text' id='second-input-02'></input>
</td>
</tr>
</table>
<button>Test</button>
Try this: use eq()
var total = 0;
$("#table1 tr").each(function () {
var input = $(this).find('input');
if (input.length == 2) {
total += input.eq(0).val() * input.eq(1).val();
}
console.log(total)
});
DEMO
$("#table1 tr").each(function() {
var amount1 = $(this).find("td:nth-child(2)").val();
var amount2 = $(this).find("td:nth-child(3)").val();
total = total + (parseFloat(amount1) * parseFloat(amount2));
});
Here i have added few codes. please check it out.
$("#calculate_btn").click(function(){
var total=0;
var row_mux=1;
$("#table1 tr").each(function(key,val){
$(val).find("input").each(function(k,v){
row_mux*=parseFloat($(v).val());
});
total=row_mux++;
});
alert(total);
$("#table1 tr:last").find("td:last").html(total);
});
demo