0

I'm working on improving my vanilla javascript. I'm trying to get this delete button to work. I don't know what is blocking it. I can't even click on and get the event.target of the button or trash can. It only clicks on the 'li'.

I've tried putting the delete functionality into a separate function of it's own but then I couldn't loop through the added tasks. I'm open to methods with adding an id or without needing an id.

const todoInputEl = document.querySelector('.todo__input');
const todoListEl = document.querySelector('.todo__list');
const todoItemEls = document.querySelectorAll('.todo__item');


function addListItem() {
  todoInputEl.addEventListener('keypress', function(event) {
    if (event.keyCode === 13) {
      let newListItem = createListItem(todoInputEl.value);
      todoListEl.insertBefore(newListItem, todoListEl.childNodes[0]);
      todoInputEl.value = '';
    }
    const deleteButtonEls = document.querySelectorAll('.delete-task');
    for (let i = 0; i < deleteButtonEls.length; i++) {

      deleteButtonEls.addEventListener('click', function() {
        this.parentNode.remove(e);
      })
    }
  })
};

function createListItem(text) {
  const newListElement = document.createElement('li');
  newListElement.innerHTML = `
        <span class="task-text">${text}</span>
        <button class="delete-task">Delete<i class="fas fa-trash"></i></button>
        `;
  newListElement.setAttribute("class", "todo__item");
  return newListElement;
};


function toggleDone() {
  todoListEl.addEventListener('click', function(event) {
    console.log(event)
    if (event.target.classList.contains('todo__item')) {
      event.target.classList.toggle('done');
    }
  })
};


addListItem();
toggleDone();
<div class="container">
  <div class="todo">
    <div class="todo__header">
      <h1 class="todo__title">to-do's</h1>
      <label for="todo input">
          <input class="todo__input" type="text" placeholder="enter a todo">
      </label>
    </div>
    <div class="todo__body">
      <ul class="todo__list">
        <!-- <li class="todo__item">Do your laundry</li>
                        <li class="todo__item">Create a video</li>
                        <li class="todo__item">Edit video content</li> -->
      </ul>
    </div>
  </div>
</div>java
Petar Vasilev
  • 4,281
  • 5
  • 40
  • 74
  • `Uncaught TypeError: deleteButtonEls.addEventListener is not a function` see: "[what do `querySelectorAll()` and `getElementsBy*` methods return?](https://stackoverflow.com/questions/10693845/what-do-queryselectorall-and-getelementsby-methods-return)" – David Thomas Sep 14 '21 at 22:10

1 Answers1

1

your deleteButtonEls is firing off every time you have a keypress event

and its returning:

"TypeError: deleteButtonEls.addEventListener is not a function
    at HTMLInputElement.<anonymous>"

EDIT(Fixed): not sure if this is what your looking for but this works


const todoInputEl = document.querySelector('.todo__input');
const todoListEl = document.querySelector('.todo__list');
const todoItemEls = document.querySelectorAll('.todo__item');


function addListItem() {
  todoInputEl.addEventListener('keypress', function(event) {
    if (event.keyCode === 13) {
      let newListItem = createListItem(todoInputEl.value);
      todoListEl.insertBefore(newListItem, todoListEl.childNodes[0]);
      todoInputEl.value = '';
    }

  })
};

function deleteListItem(target){
  const x = target.getElementsByClassName('delete-task')
  
  x[0].addEventListener('click', function() {
        target.remove();
      })
}
function createListItem(text) {
  const newListElement = document.createElement('li');
  newListElement.innerHTML = `
        <span class="task-text">${text}</span>
        <button class="delete-task">Delete<i class="fas fa-trash"></i></button>
        `;
  newListElement.setAttribute("class", "todo__item");
  deleteListItem(newListElement)
  return newListElement;
};


function toggleDone() {
  todoListEl.addEventListener('click', function(event) {
//     console.log(event)
    if (event.target.classList.contains('todo__item')) {
      event.target.classList.toggle('done');
    }
  })
};


addListItem();
toggleDone();


this passes the created element to deleteListItem() after you set the attribute todo__item to it

gets the class with 'delete-task' and sets a event listener on the element which is the button with that class name

on click it removes the whole element

your toggleDone() function never worked comment if you need help with that didn't want to fix something you want to try on yourself

Mochi
  • 19
  • 3
  • Thanks for your help. I'm not sure I understand how this [0] index works. x[0].addEventListener('click', function() {... I changed it to loop through all the tasks. It makes more sense to me. for(let i=0; i – BaldeepParihar Sep 15 '21 at 03:58
  • when you use ```getElementsByClassName``` it returns a ```HTMLCollection``` of elements, which is an array-like object. in order to access it and get the first item from it we use index 0 if you don't tell which index to get it will return the whole array-like object instead – Mochi Sep 15 '21 at 16:06