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

Time:03-17

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.

CodePudding user response:

Try this...

deleteButton.addEventListener('click', function(event) {
    const targetToDo = event.currentTarget.parentNode;
    console.log(targetToDo.parentNode);
    setTimeout(() => li.remove(), 0); // The li that will be removed also has the delete button as child and we are inside the event handler of that child. A setTimeout() works here
  });

Illustration

Hopefully, following rudimentary setup along with the code in OP for illustration is closer to the needs of the OP.

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); //<--- This condition check is insignificant as we are setting it to false in the previous statement

  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.parentNode.remove();
    // targetToDo.remove();
    setTimeout(() => li.remove(), 0);
  });
  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>


WYSIWYG => WHAT YOU SHOW IS WHAT YOU GET

CodePudding user response:

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>

  • Related