Like Mike commented, you're adding a new handler to the elements again on every enter keypress, instead use event delegation
To further explain:
When you add an event handler as shown below, jQuery looks through the DOM and adds the handler directly to any elements that have the todo-container class.
$('.todo-container').on('click', function()...
or
$('.todo-container').click(function()...
An important caveat is that this will only add the handler to elements that currently exist on the page.
You saw this results of this when you realized that the handler did not function on newly created (dynamic) elements.
Not quite understanding why it didnt work, you moved the event bindings into the handler for the keyup effectively calling the binding each time a new element is created. This seemed to work at first but in practice is flawed because this again adds the handler directly to any elements that have the todo-container
class. including the elements that already have a handler defined from a previous call.
In the below example we move the bindings back outside the keyup handler and use $('#todos').on('click', '.todo-container',
to attach the listener to the '#todos'
element (which always exists on the page). Then, any time you click inside that element, it checks if the child you clicked had the class "todo-container" and if so, will fire off your code. This is event delegation. This will catch events on any dynamic element that matches the selector
$(document).on('keypress', function(e) {
// Add todo
if (e.which === 13 && $('.input-field').val() != "") {
$('#todos').prepend(todoTemplate);
var todo = $('.todo-container');
$('#todos').children().first().find(todo).html($('.input-field').val());
$('.input-field').val("");
}
})
// Remove todo
$('#todos').on('click', '.todo-container-delete', function() {
$(this).parent().remove();
})
// Toggle line-through todo
$('#todos').on('click', '.todo-container', function() {
$(this).toggleClass('line-through');
console.log("hello")
})
Fix two, more specific targeting with :last
You could actually leave the bindings inside the keyup handler, if you specifically target only the newly added element like this:
$('#todos .todo-container:last').on('click', function(){
or
$('#todos .todo-container:last').click(function(){
Fix three, (not really recommended but possible) .off()
You could also leave the bindings inside the keyup handler, if you use .off() to remove the handlers from the previous elements before adding it to all the elements again like this:
$('.todo-container').off().on('click', function(){
I'd avoid this method though because if you dont specifically target a handler to remove (see documentation for how), you are removing all handlers applied to that element wich could definitely bite you down the road