JavaScript Todo List help

I’m making a javascipt todolist and right now and I’m having trouble with the delete and complete buttons. When I try to run a function function deleteListItem() and try to alert when the button is pressed, it alerts it on my first li which is actually just from my html. But it won’t send out an alert from an li after I have pressed the enter button. I feel like I’ve made some small mistake, but I can’t seem to find it. I have my Codepen here

So at the risk of falling right back down the rabbit hole (this has been a very divisive subject today), the issue is that you’re trying to create listeners on element that don’t exist yet.

The solution is known as ‘event delegation.’ Basically, rather than listening for the click on the buttons, listen for the click on the element that will contan your todos, and that already exists.

When a button within that cotainer is clicked, the handler at the container will be given an Event object. One of the properties of that is event.target, which will tell you precicely which button was clicked.

I would take a look on MDN (http://developer.mozilla.org/), and search for ‘event delegation.’

So I added an ID to the <ul> and put that in my code as `

var deleteButton = document.getElementById("todo")

var completeButton = document.getElementById("todo")`

that alerts it now whenever I click on the buttons after I create a new list, but now if I click on the complete button first, it runs both the function deleteListItem() and function completeListItem()
for both buttons. How do I implement the event.target into my code?

Don’t bind all individual functions to the click on wrapper of your control.
Just bind one function that will parse event and choose function to call based on that.
Like this for example:

var todoWrapper = document.getElementById("todo");
todoWrapper.addEventListener("click",todoClickHandler);

function todoClickHandler(event){
  switch (event.target.id) {
    case "Complete":
      completeListItem();
      break;
    case "Remove"
      deleteListItem();
      break
  }
}

I am sure you will be able to figure out the rest.

I’m not sure I understand what your main goal is here, so I’ve just made up my own example of a list of tasks where a task is created by first defining it in the input field, and then on a click event, it gets displayed with a couple of buttons, one to remove the task from the list and one to mark it as completed. It also displays alerts on clicks.

HTML

<input id="userInput" type="text" placeholder="New item" maxlength="27" required>
<ul id="mylist">
</ul>

<button id="display">Display It!</button>

JavaScript

var input = document.getElementById('userInput');
document.getElementById('display').addEventListener('click', displayer);

function displayer() {
  var el = input.value;
  if (el.length === 0) {
    alert("Must enter something in input field");
    return;
  }

  var myDiv = document.createElement('div');
  myDiv.setAttribute("class", "todo-container");

  var item = document.createElement("li");
  var node = document.createTextNode(el);

  item.appendChild(node);
  myDiv.appendChild(item);

  var element = document.getElementById("mylist");
  element.appendChild(myDiv);

  var btn1 = document.createElement("button");
  var r = document.createTextNode("Remove");
  btn1.appendChild(r);
  myDiv.appendChild(btn1);

  btn1.addEventListener('click', function(e) {
    e.currentTarget.parentNode.remove();
    setTimeout(() => {
      alert('Item was deleted');
    }, 300)

  }, false);

  var btn2 = document.createElement("button");
  var c = document.createTextNode("Complete");
  btn2.appendChild(c);
  myDiv.appendChild(btn2);
  btn2.addEventListener('click', function(e) {
    this.parentNode.removeChild(this);
    let task = item.innerHTML;
    item.innerHTML = task + " completed";
    setTimeout(() => {
      alert("This item was completed");
    }, 300)
  }, false);

  input.value = "";
}

CSS

.todo-container {
  display: flex;
  flex-direction: row;
}

li {
  padding: 10px;
}

You can just throw each part (html, css, and js) into their respective sections in a pen at CodePen to see it work.