I Created a small test application that should allow the user to create:
I learned that dynamically added elements don't get an event bound to them (based on this: Event binding on dynamically created elements? ) so I tried to attach the event on a single static ancestor. Unfortunately, this leads to every single click event being triggered when just one button was pressed.
<head>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<title>Test Page</title>
</head>
<body>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>
</body>
<script>
var btnDeleteListItem = $(".btnDeleteListItem");
var btnAddListElement = $(".btnAddListElement");
var btnDeleteList = $(".btnDeleteList");
var btnAddList = $(".btnAddList");
var container = $("#container");
container.on("click",btnDeleteListItem, function (e) {
$(this).parent().remove();
console.log("list item deleted");
});
container.on("click",btnAddListElement, function (e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$("ol").append(html);
console.log("list item added");
});
container.on("click",btnDeleteList, function (e) {
$(this).parent().remove();
console.log("list deleted");
});
btnAddList.on("click", function(e){
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
</script>
</html>`
Is there a way to segregate the click events?
The problem is because, although you're using delegated event handlers, you're only selecting the elements on load of the DOM. To fix this pass the selector argument to on()
as a string. That way the selector will be matched as the click
events bubble through the #container
, not just for specific element instances.
Also note that you need to make the append()
call only on the ol
which is relative to the .btnAddListElement
button which was clicked, otherwise you end up adding a new li
to every list. To do this, change $('ol')
to $(this).prev('ol')
.
var $container = $("#container");
$container.on("click", ".btnDeleteListItem", function(e) {
$(this).parent().remove();
console.log("list item deleted");
});
$container.on("click", '.btnAddListElement', function(e) {
var html = '<li> Just added <button class="btnDeleteListItem">Delete</button></li>';
$(this).prev("ol").append(html);
console.log("list item added");
});
$container.on("click", '.btnDeleteList', function(e) {
$(this).parent().remove();
console.log("list deleted");
});
$container.on('click', '.btnAddList', function(e) {
var html = '<div class="listContainer"><ol><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li><li>Other list <button class="btnDeleteListItem">Delete</button></li></ol><button class="btnAddListElement">+Add List Item</button><button class="btnDeleteList">Delete List</button></div>';
$(html).insertBefore($(this));
console.log("list added");
});
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<div id="container">
<div class="listContainer">
<ol>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
<li>First list <button class="btnDeleteListItem">Delete</button></li>
</ol>
<button class="btnAddListElement">+Add List Item</button>
<button class="btnDeleteList">Delete List</button>
</div>
<button class="btnAddList">+Add List</button>
</div>