Search code examples
javascriptremovechild

Deleting li using Node.remove() in JavaScript is not working


I am currently trying to delete li by clicking deleteButton. This is my full JS code.

const form = document.querySelector('#form');
const savedList = document.getElementById('savedList');
const doneList = document.getElementById('doneList');

form.addEventListener('submit', (e) => {
  const li = document.createElement('li');
  li.innerText = document.getElementById('input').value;
  li.id = li.innerText;
  li.isDone = false;
  li.isDone ? doneList.append(li) : savedList.append(li);

  const deleteButton = document.createElement('button');
  deleteButton.innerText = 'x';
  deleteButton.id = 'deleteButton';
  li.append(deleteButton);

  li.addEventListener('click', () => {
    li.isDone ? (li.isDone = false) : (li.isDone = true);
    li.isDone ? doneList.append(li) : savedList.append(li);
  });

  deleteButton.addEventListener('click', function(event) {
    const targetToDo = event.currentTarget.parentNode;
    console.log(targetToDo.parentNode);
    targetToDo.parentNode.remove(targetToDo);
    targetToDo.remove();
  });
  e.preventDefault();
});
<form id="form">
  <input id="input" type="text" />
  <button type="submit">Submit</button>
</form>

<ul id="savedList"></ul>
<ul id="doneList"></ul>

However, other lis except targetToDo are being deleted. I've tried debugging with console.log but targetToDo and its parentNode is okay. I can see li for a targetToDo and ul for its parentNode. How can I fix this? Thanks in advance.


Solution

  • You need to use event.stopPropagation() at the end of your deleteButton.addEventListener. It will fix your problem.

    What is happening with your code is as below.

    • When you click on x button it will invoke click event for that button as well as click event of li.
    • So, first it will invoke click event of x & from deleteButton.addEventListener it will remove your li.
    • Then it will invoke click event of li and as per code from li.addEventListener it will move li to other ul.
    • The stopPropagation() method of the Event interface prevents further propagation of the current event in the capturing and bubbling phases.
    • So if you use event.stopPropagation() in your deleteButton.addEventListener then it will prevent further invoke of li click event and it won't be able to add li again to other ul.

    Try code below.

    const form = document.querySelector('#form');
    const savedList = document.querySelector("#saved-list");
    const doneList = document.querySelector("#done-list");
    
    form.addEventListener('submit', (e) => {
      const li = document.createElement('li');
      li.innerText = document.getElementById('input').value;
      li.id = li.innerText;
      li.isDone = false;
      li.isDone ? doneList.append(li) : savedList.append(li);
    
      const deleteButton = document.createElement('button');
      deleteButton.innerText = 'x';
      deleteButton.id = 'deleteButton';
      li.append(deleteButton);
    
      li.addEventListener('click', () => {
        li.isDone ? (li.isDone = false) : (li.isDone = true);
        li.isDone ? doneList.append(li) : savedList.append(li);
      });
    
      deleteButton.addEventListener('click', function(event) {
        const targetToDo = event.currentTarget.parentNode;
        console.log(targetToDo.parentNode);
        // targetToDo.parentNode.remove(targetToDo);
        targetToDo.remove();
        
        // Add below line.
        event.stopPropagation();
      });
      e.preventDefault();
    });
    <form id="form">
      <input id="input" type="text" />
      <button type="submit">Submit</button>
    </form>
    
    <ul id="saved-list"></ul>
    <ul id="done-list"></ul>