dev71515
dev71515

Reputation: 7

how to make a button that deletes an element created with createElement?

I am trying to build a todoList with vanilla js and trying to figure out how to make a button that deletes/removes an element

My code breaks and deletes everything. I tried assigning a parent variable and removing it but that didn't work

//selectors!
const todoBtn = document.querySelector('.todo-button');
const TodoList = document.querySelector('.todo-list');
const todoInput = document.querySelector('.todo-input');
//const TrashButton = document.querySelector('.trashbtn')

// event Listeners

todoBtn.addEventListener('click', Testgo);
//TrashButton.addEventListener('click' ,  Testing)
TodoList.addEventListener('click', Testing);

//Functions!

function Testgo(event) {
  event.preventDefault();

  const TodoDiv = document.createElement('div');
  TodoDiv.classList.add('todoDiv');

  const newTodo = document.createElement('li');
  newTodo.innerText = todoInput.value;
  newTodo.classList.add('newTodo');

  TodoDiv.appendChild(newTodo);

  const TodoBtn = document.createElement('button');
  TodoBtn.classList.add('newbtn');
  TodoBtn.innerText = 'Edit';
  TodoBtn.innerHTML = "<i class='fas fa-check'></>";

  const TrashBtn = document.createElement('button');
  TrashBtn.classList.add('trashbtn');
  TrashBtn.innerText = 'delete';
  TrashBtn.innerHTML = "<i class='fas fa-trash'></>";
  //document.parentNode.removeChild()
  //TrashBtn.setAttribute('TrashB' , TrashB())

  TodoList.appendChild(TodoDiv);
  TodoList.appendChild(TodoBtn);
  TodoList.appendChild(TrashBtn);

  todoInput.value = '';

  console.log(TodoBtn.classList);

  // function TrashB(){
  //   const TrashInput = document.getElementsByClassName('newTodo')
  //   TrashInput.remove()
  // }
}

//TrashBtn.addEventListener('click' , Testing)

function Testing(event) {
  const item = event.target;

  const element = item.parentElement;

  if (item.classList.contains('trashbtn')) {
    element.remove();
  }

  // element.parentNode.removeChild(element)
}
<header>
  <h1>ToDo</h1>
</header>

<form>
  <input type="text" placeholder="Add" class="todo-input" />

  <button id="button" class="todo-button" type="submit"><i class="fas fa-plus-square"></i></button>
</form>

<div class="test1">
  <p>hi</p>
</div>
<div class="test2">
  <p>ho</p>
</div>

<div class="todo-container">
  <ul class="todo-list">
    <li class="todo">insert new stuff here</li>

    <button class=".btn-E">edit</button>
    <button class=".btn-D">delete</button>
  </ul>
</div>

Upvotes: 0

Views: 360

Answers (1)

Andrew L
Andrew L

Reputation: 5486

There's a couple things to note

  1. I believe you were getting at "event delegation" which I do in the below example and is needed to handle events for dynamically created buttons for the todo list.

  2. I would suggest adding 1 div for each element with child nodes. This makes it easy to remove the element. We can just remove the parent node, which holds everything for that item.

  3. To do the above I suggest changing from using ul to just divs

  4. Be careful if using icons too since the event delegation below looks for click events on buttons only. You can update this if needed.

Here is a full example

const todoBtn = document.querySelector('.todo-button');
const TodoList = document.querySelector('.todo-list');
const todoInput = document.querySelector('.todo-input');

todoBtn.addEventListener('click', Testgo);

// event delegation for dynamically added list items
document.querySelector(".todo-container").addEventListener("click", function(e) {
  // if a button was clicked within the todo-container we will remove its parent (the housing div which holds the whole list item text and 2 buttons)

  if (e.target && e.target.nodeName == "BUTTON") {
    if (e.target.classList.contains("trashbtn")) {
      e.target.parentNode.remove();
    }
    if (e.target.classList.contains("editbtn")) {
      console.log("edit button clicked for", e.target.parentNode)
    }
  }
});

function Testgo(event) {
  event.preventDefault();

  // create the div to house the list text and 2 buttons
  const TodoDiv = document.createElement('div');
  TodoDiv.classList.add('todoDiv');
  // add the text from the input
  TodoDiv.innerText = todoInput.value;
  TodoDiv.classList.add('newTodo');

  // create the buttons and add them to the housing div
  const TodoBtn = document.createElement('button');
  TodoBtn.classList.add('editbtn');
  TodoBtn.innerText = 'Edit';

  const TrashBtn = document.createElement('button');
  TrashBtn.classList.add('trashbtn');
  TrashBtn.innerText = 'delete';

  TodoDiv.appendChild(TodoBtn);
  TodoDiv.appendChild(TrashBtn);

  // append the 1 div to the list that houses the item text and 2 buttons.
  TodoList.appendChild(TodoDiv);

  todoInput.value = '';
}
<header>
  <h1>ToDo</h1>
</header>

<form>
  <input type="text" placeholder="Add" class="todo-input" />

  <button id="button" class="todo-button" type="submit"><i class="fas fa-plus-square"> add</i></button>
</form>

<div class="todo-container">
  <div class="todo-list">
  </div>
</div>

Upvotes: 1

Related Questions