1

I'm trying to create a vanilla javascript To-do application. I don't want to use jquery because I don't know how that works ;)

I need an input where I can fill in a task, click a button to add it, and also a button to clear the input field.

When I have added the task, there should be a button with a "X" on it to delete that specific list item.

I am lost how to create button inside a li element that deletes that li element on click.

const menu = document.getElementById("ul");

function callThisOne() {
  var Task = document.getElementById("addToDo").value;
  menu.appendChild(Create(Task));
  document.getElementById("addToDo").value = '';
}

function Create(name) {
  let listitem = document.createElement("li");
  listitem.textContent = name;
  let deleteButton = document.createElement("button")
  deleteButton.onclick = function() {
    deleteButton.remove
  }
  let complete = deleteButton + listitem;

  return complete;


}
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet'>

<div id="divContainer">
  <div id="Title">
    <p>To-Do list</p>
  </div>
  <div id="divAddToDo">
    <input id="addToDo" type="text" placeholder="Make a new task"><br>
    <input id="addButton" onclick="callThisOne()" type="button" value="Add!">
    <button class="butong" onclick="document.getElementById('addToDo').value = ''">Clear</button>
  </div>
  <div id="list">
    <ul id="ul">
      <li>Dit is alleen om even te</li>
      <li>laten zien dat het werkt</li>
    </ul>
  </div>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Will Cuber
  • 13
  • 3

3 Answers3

1

This is what delegation is for:

Any click in the menu on any delete button will now remove the LI it is in

I also removed the inline handlers, because that is recommended

const menu = document.getElementById("ul");

function createTask(taskName) {
  let listitem = document.createElement("li");
  listitem.textContent = taskName;
  let deleteButton = document.createElement("button")
  deleteButton.textContent = 'Delete';
  deleteButton.classList.add('delete')
  deleteButton.style.marginLeft = '5px';
  listitem.appendChild(deleteButton);
  return listitem;
}

document.getElementById('addButton').addEventListener('click', function() {
  var taskName = document.getElementById("addToDo").value;
  if (taskName.trim() === "") return; // no need to add an empty task
  menu.appendChild(createTask(taskName));
  document.getElementById("clear").click();
})

document.getElementById('clear').addEventListener('click', function() {
  document.getElementById('addToDo').select();
})

menu.addEventListener('click', function(e) {
  const tgt = e.target;
  if (tgt.classList.contains('delete')) tgt.closest('li').remove();
})
ul {
  font-family: 'Montserrat', sans-serif;
  font-weight: 100;
}
<link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet'>

<div id="divContainer">
  <div id="Title">
    <p>To-Do list</p>
  </div>
  <div id="divAddToDo">
    <input id="addToDo" type="text" placeholder="Make a new task"><br>
    <input id="addButton" type="button" value="Add!">
    <button class="butong" id="clear">Clear</button>
  </div>
  <div id="list">
    <ul id="ul">
      <li>Dit is alleen om even te</li>
      <li>laten zien dat het werkt</li>
    </ul>
  </div>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0
  1. You can append the delete button to the list item.
  2. You can call .remove on the list item inside the click event listener since you have a reference to it.

const menu = document.getElementById("ul");

function callThisOne() {
  var Task = document.getElementById("addToDo").value;
  menu.appendChild(Create(Task));
  document.getElementById("addToDo").value = '';
}

function Create(name) {
  let listitem = document.createElement("li");
  listitem.textContent = name;
  let deleteButton = document.createElement("button")
  deleteButton.textContent = 'Delete';
  deleteButton.style.marginLeft = '5px';
  deleteButton.onclick = function() {
    listitem.remove();
  }
  listitem.appendChild(deleteButton);
  return listitem;
}
<!DOCTYPE html>
<html>

<head>
  <link href='https://fonts.googleapis.com/css?family=Montserrat' rel='stylesheet'>
  <link href="ToDo.css" rel="stylesheet">
</head>

<body>

  <div id="divContainer">
    <div id="Title">
      <p>To-Do list</p>
    </div>
    <div id="divAddToDo">
      <input id="addToDo" type="text" placeholder="Make a new task"><br>
      <input id="addButton" onclick="callThisOne()" type="button" value="Add!">
      <button class="butong" onclick="document.getElementById('addToDo').value = ''">Clear</button>
    </div>
    <div id="list">
      <ul id="ul">
        <li>Dit is alleen om even te</li>
        <li>laten zien dat het werkt</li>
      </ul>
    </div>
  </div>
</body>

</html>
Unmitigated
  • 76,500
  • 11
  • 62
  • 80
0

All you need is for the dynamically created "X" button to find the nearest li ancestor, which can be done with the .closest() method and then call .remove() on that.

Other:

You should really not be using inline HTML event attributes like onclick. This is a 25+ year old technique for setting up events that just won't die the death it deserves because it's easy to do and most new coders just copy someone else's code that unwittingly used it. Not to mention that the infamous W3 Schools site still incorrectly advocates this approach. Instead, do all your event binding in the JavaScript and instead of the other very old technique of using event properties, such as onclick, use the modern .addEventListener() which is more robust.

You can see in the code below how clean the HTML is, because there's nothing there but HTML.

const input = document.querySelector("input");
const list = document.querySelector("ul");
document.querySelector("button.clear").addEventListener("click", function(evt){
  list.innerHTML = "";
});

document.querySelector("button").addEventListener("click", function(evt){
  const item = document.createElement("li");
  item.textContent = input.value;
  input.value = "";
  const delBtn = document.createElement("button");
  delBtn.classList.add("delete");
  delBtn.textContent = "X"
  
  delBtn.addEventListener("click", function(evt){
    // Find the nearest <li> ancestor element and remove it
    this.closest("li").remove();
  });
  
  item.appendChild(delBtn);
  list.appendChild(item);
});
.delete { font-weight:bold; margin-left:1em; }
<input><button>ADD</button>
<ul></ul>
<button class="clear">Clear</button>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71