William William - 28 days ago 7
CSS Question

toggleClass, and removing li's with a button click

I cannot figure out two issues I am having with Jquery.


  1. The delete button works, but not for newly appended items. Only for items originally there. Ex. milk, bread. Milk, and bread for example are originally there from the html, and have the same buttons. The delete button works for those li's, but newly appended li's from the submission box, don't work at all and the buttons classes must not even apply, because there is no spacing between the buttons on newly appended divs.

  2. The toggleClass for adding a class of check will not toggle. 0 errors. No matter what I use I cannot get it to toggle. The problem is it is supposed to add a class that strikethrough ('shopping-item__checked'), and will not after hours of trying to figure it out.



This is a beginner question i'm sure. Thanks.
Here is a link to the full project:
https://i.stack.imgur.com/2H3mV.png
https://github.com/Masonwharr/shoppinglist/tree/master/Shopping-List



$(document).ready(function() {
$('#js-shopping-list-form').submit(function(event) {
event.preventDefault();
var inputfield = $('#entry').val();
console.log(inputfield);
$('.shopping-list').append('<li> <span class="shopping-item">' + inputfield + '</span>' + '<div class="shopping-item-controls">' + '<button class="shopping-item-toggle"><span class="button-label">check</span></button>' + '<button class="shopping-item-delete"><span class="button-label">delete</span></button>' + '</div></li>');
// This is incorrect, and adds an outside empty box. $('.shopping-list').append('<div class="shopping-item-controls"> <button class="shopping-item-toggle">' + '</button> </div>');
//$('inputfield').appendTo('body').addClass('.shopping-item');
});


$('.shopping-item-toggle').on("click", function() {
$(this).closest('span', '.shopping-item').toggleClass('shopping-item__checked');
});


$('.shopping-item-delete').mousedown(function(event) {
var inputfield = $('#entry').val();
event.preventDefault();
$(this).parent('div').parent('li').remove();
});
});

<!DOCTYPE html>
<html lang="en">

<head>
<title>Shopping List</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="js/script.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="CSS/styles.css">
</head>

<body>
<div class="container">
<h1>Shopping List</h1>

<form id="js-shopping-list-form">
<label for="shopping-list-entry">Add an item</label>
<input type="text" name="shopping-list-entry" placeholder="e.g., broccoli" id="entry">
<button type="submit">Add item</button>
</form>

<ul class="shopping-list">
<li>
<span class="shopping-item">apples</span>
<div class="shopping-item-controls">
<button class="shopping-item-toggle">
<span class="button-label">check</span>
</button>
<button class="shopping-item-delete">
<span class="button-label">delete</span>
</button>
</div>
</li>
<li>
<span class="shopping-item">oranges</span>
<div class="shopping-item-controls">
<button class="shopping-item-toggle">
<span class="button-label">check</span>
</button>
<button class="shopping-item-delete">
<span class="button-label">delete</span>
</button>
</div>
</li>
<li>
<span class="shopping-item shopping-item__checked">milk</span>
<div class="shopping-item-controls">
<button class="shopping-item-toggle">
<span class="button-label">check</span>
</button>
<button class="shopping-item-delete">
<span class="button-label">delete</span>
</button>
</div>
</li>
<li>
<span class="shopping-item">bread</span>
<div class="shopping-item-controls">
<button class="shopping-item-toggle">
<span class="button-label">check</span>
</button>
<button class="shopping-item-delete">
<span class="button-label">delete</span>
</button>
</div>
</li>
</ul>
</div>

</body>

</html>





`

Answer

jQuery does not register the event handlers for dynamically created elements on the page. So what you can do is put an event listener on a parent static div (in your case for shopping-list).

The idea is to delegate the events to that wrapper, instead of binding handlers directly on the dynamic elements.

So, this would do the trick for delete:

$(".shopping-list").on("click", ".shopping-item-delete", function(event) {
    var inputfield = $('#entry').val();
    $(this).parent('div').parent('li').remove();
    event.preventDefault();
});

You can check this JSFiddle - https://jsfiddle.net/3a6ddcd7/

Edit:

JSFiddle has been updated with check working and here is the change:

$('.shopping-item-toggle').on("click", function() {
    $(this).closest('li').children().first().toggleClass('shopping-item__checked');
});

Hope this helps!