2

I am trying to add a child element to a parent element as follows:

  • li to be added to ul
  • Either when the enter button is clicked or the enter key on the keyboard is pressed, a new li and delete button should get added to ul.

My code isn't working right. Can someone help me with this, please?

HTML:

<h1>Simple Add/Remove Task</h1>
<h2>To do List</h2>

<input type="text" placeholder="enter your tasks" id="userInput">
<button id="enter">Enter</button>
<ul>
  <li class="todos">Wake up <button>Delete</button></li>
  <li class="todos">Study<button>Delete</button></li> 
</ul>

CSS:

.done {
  text-decoration: line-through;
}

Javascript:

var listItems = document.querySelectorAll(".todos");
var input = document.getElementById("userInput");
var ul = document.querySelectorAll("ul");
var button = document.getElementById("enter");

button.addEventListener("click", function(){
  if(input.value.length>0){
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(input.value));
    ul.appendChild(li);
    input.value = "";
  }
});

input.addEventListener("keypress", function(){
  if(input.value.length > 0 && event.which === 13){
    var li = document.createElement("li");
    li.appendChild(document.createTextNode(input.value));
    ul.appendChild(li);
    input.value = "";
  }
});

for (var i = 0; i<listItems.length; i++){
  listItems[i].addEventListener("click", function(){
    this.classList.toggle("done");
  });
}

3 Answers 3

3

querySelectorAll returns NodeList. NodeList does not contain appendChild method. So either try to replace ul.appendChild with ul[0].appendChild or just refactor your code

Sign up to request clarification or add additional context in comments.

Comments

2

This solution modifies your item-adding code to include a delete button (and refactors the code into a dedicated function.)

All delete buttons (marked with a "delete-btn" class) trigger list-item removal. (The click event bubbles up to the ul, where the listener is attached.)

See the in-code comments for further explanation.

// Identifies DOM elements
const
  listItems = document.querySelectorAll(".todos"),
  input = document.getElementById("userInput"),
  ul = document.getElementById("the-list"), // (NOT `querySelectorAll`)
  button = document.getElementById("enter");

// Conditionally calls addItem function when button is clicked
button.addEventListener("click", function() {
  if (input.value.length > 0) {
    addItem();
  }
});

// Conditionally calls addItem function when ENTER is pressed
input.addEventListener("keypress", function() {
  if (input.value.length > 0 && event.which === 13){
    addItem();
  }
});

// Adds an item to the list (when called by either listener)
function addItem(){
  const
    li = document.createElement("li"),
    txt = document.createTextNode(input.value),
    btn = document.createElement("button");
  // Puts txt & btn inside li
  li.appendChild(txt);
  btn.textContent = "Delete";
  btn.classList.add("delete-btn"); // For later reference
  li.appendChild(btn);  

  ul.appendChild(li); // Puts li inside ul
  input.value = ""; // Clears input
}

// Listens for clicks on the `ul` or its descendants, even if the
//   clicked element gets dynamically added later
ul.addEventListener("click", function(event) {
  // Listeners can automatically access triggering events
  const clickedElement = event.target; // Events have a target property
  if(clickedElement.classList.contains("delete-btn")){
    // Finds ancestor elements and removes li from ul
    const
      li = clickedElement.closest("li"),
      ul = li.closest("ul");
    ul.removeChild(li); // (Or we could add "done" to li's classList)
  }
});
.delete-btn{
  margin-left: 1em;
}

/*
.done {
  text-decoration: line-through;
}
*/
<h1>Simple Add/Remove Task</h1>
<h2>To do List</h2>

<input type="text" placeholder="enter your tasks" id="userInput">
<button id="enter">Enter</button>

<ul id="the-list">
  <li class="todos">Wake up<button class="delete-btn">Delete</button></li>
  <li class="todos">Study<button class="delete-btn">Delete</button></li>
</ul>

2 Comments

a bit frustrated right now. Can you point me towards a good source for learning Dom manipulation? I will try this code and thanks in advance.
Sure, MDN is many people's #1 source for a lot of Web-development info. Their intro to DOM manipulation seems like a great place to start: developer.mozilla.org/en-US/docs/Learn/JavaScript/…
0

Change this,

var ul = document.querySelectorAll("ul");

to this,

var ul = document.querySelector("ul");

As you have only one ul in your html.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.