The initial situation is an HTML table with two rows. A button can be used to add further rows via jquery. Interestingly, the newly added rows do not respond to .change(). Do you have any idea why?
<table>
<thead>
<tr>
<th>Id</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Street</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
</tbody>
</table>
<button id="addItem">Add Item</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
$("#addItem").click(function() {
$('table tbody tr:last').after(' <tr>\n'
' <td><input type="number" ></td>\n'
' <td><input type="text" ></td>\n'
' <td><input type="text" ></td>\n'
' <td><input type="text" ></td>\n'
' <td><input type="text" ></td>\n'
' </tr>');
});
$(".id").change(function () {
console.log("changed")
})
</script>
CodePudding user response:
you should try using this code
$(document).on('change', 'elementSelector', callback);
element selector here is the rows. callback is the function that you want to run whenever the rows changes. It didn't work because the rows that you just made using jquery is was not on the dom when the jquery is initialized I guess.
CodePudding user response:
There are two primary ways to address this.
- Assign Change Callback to the Element after it has been created / appended
- Delegate the
change
event using.on()
to dynamic elements
Here is an example of each. First standard .change()
assignment.
$(function() {
function log(str) {
console.log(str);
}
$("#addItem").click(function() {
var target = $("table tbody");
var row = $("<tr>").appendTo(target);
var cells = [{
type: "number",
class: "id"
}, {
type: "text",
class: "firstname"
}, {
type: "text",
class: "lastname"
}, {
type: "text",
class: "street"
}, {
type: "text",
class: "city"
}];
$.each(cells, function(i, p) {
$("<td>").appendTo(row);
$("<input>", p).appendTo($("td", row).eq(i));
});
$("input:eq(0)", row).change(function(event) {
console.log("Input Changed, row: " row.index() ", column: " $(this).index() ", New Value: " $(this).val());
});
});
$(".id").change(function() {
console.log("Input Changed, row: " $(this).closest("tr").index() ", column: " $(this).index() ", New Value: " $(this).val());
})
});
<table>
<thead>
<tr>
<th>Id</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Street</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
</tbody>
</table>
<button id="addItem">Add Item</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
Here is a Delegate example.
$(function() {
function log(str) {
console.log(str);
}
$("#addItem").click(function() {
var target = $("table tbody");
var row = $("<tr>").appendTo(target);
var cells = [{
type: "number",
class: "id"
}, {
type: "text",
class: "firstname"
}, {
type: "text",
class: "lastname"
}, {
type: "text",
class: "street"
}, {
type: "text",
class: "city"
}];
$.each(cells, function(i, prop) {
$("<td>").appendTo(row);
$("<input>", prop).appendTo($("td", row).eq(i));
})
});
$("table > tbody").on("change", ".id", function(event) {
console.log("Input Changed, row: " $(this).closest("tr").index() ", column: " $(this).index() ", New Value: " $(this).val());
});
});
<table>
<thead>
<tr>
<th>Id</th>
<th>Firstname</th>
<th>Lastname</th>
<th>Street</th>
<th>City</th>
</tr>
</thead>
<tbody>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
<tr>
<td><input type="number" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
<td><input type="text" ></td>
</tr>
</tbody>
</table>
<button id="addItem">Add Item</button>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
They each result in the same action. You can see that is a bit less code in the Delegate method.
In the end, it is your call which method you choose to use.