Home > database >  How to add new created element in a list of Node? JavaScript
How to add new created element in a list of Node? JavaScript

Time:09-29

I am making a ToDo Application from HTML, CSS and JavaScript.

I have added a symbol in front of every list item, such that when clicked, it removes the list item.

The problem is when I try to remove pre-added list items, it works perfectly fine, but when I add a list item and then remove it, it doesn't work :(

Have a look at my code:

const toDoInput = document.querySelector("input");
const addButton = document.querySelector("button");
const listParent = document.querySelector("ul");
const removeLists = document.querySelectorAll(".remove-li");

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = '(Remove Button)';
    newDiv.append(newSpan);
    listParent.append(newDiv);
  }
};

addButton.addEventListener("click", () => {
  listItemMake();
});

toDoInput.addEventListener("keydown", (event) => {
  if (event.code === "Enter") {
    listItemMake();
  }
});

for (const removeList of removeLists) {
  removeList.addEventListener("click", () => {
    removeList.parentElement.remove();
  })
}
<h1>ToDo Application</h1>
<div class="container">
  <div class="form-container">
    <input type="text" placeholder="Add New Tasks">
    <button>Add</button>
  </div>
  <div class="list-container">
    <ul>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
    </ul>
  </div>
</div>

While I was trying to fix this issue by myself in Chrome Dev Tools, I realised that my newly created list-item do contain the remove-list button, but the remove-list button is never added in the remove-lists list and my whole fuction to remove list items is based on remove-list and hence it doesn't work. Although, I don't know how to add that element in the list.

Also, I don't really know the name of the list I'm declaring on the first 4 lines. What exactly is toDoInput(declaring on line 1)? I don't think it's an array because though I can iterate over it, I can't really use methods like push & pop. What exactly is the term, and what is the difference?

Help Appreciated :)

CodePudding user response:

Please change some code. Please add remove event function to listItemMake() function.

const toDoInput = document.querySelector("input");
const addButton = document.querySelector("button");
const listParent = document.querySelector("ul");

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = '(Remove Button)';
    newDiv.append(newSpan);
    listParent.append(newDiv);
  }
  addRemoveEvent();
};

addButton.addEventListener("click", () => {
  listItemMake();
});

toDoInput.addEventListener("keydown", (event) => {
  if (event.code === "Enter") {
    listItemMake();
  }
});

function addRemoveEvent() {
  const removeLists = document.querySelectorAll(".remove-li");
  for (const removeList of removeLists) {
    removeList.addEventListener("click", () => {
      removeList.parentElement.remove();
    })
  }
}

addRemoveEvent();
<h1>ToDo Application</h1>
<div class="container">
  <div class="form-container">
    <input type="text" placeholder="Add New Tasks">
    <button>Add</button>
  </div>
  <div class="list-container">
    <ul>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
    </ul>
  </div>
</div>

CodePudding user response:

You need to listen for click event on newly added element. hence added a click listener on newSpan element after adding it into DOM.

You are listening for event for removeLists element only but when you add a new element in the DOM, the newly doesn't have the click event. Hence, we have to listen for the event explicitly.

I hope, it answers your question. :)

const toDoInput = document.querySelector("input");
const addButton = document.querySelector("button");
const listParent = document.querySelector("ul");
const removeLists = document.querySelectorAll(".remove-li");

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = '(Remove Button)';
    newDiv.append(newSpan);
    listParent.append(newDiv);
    newSpan.addEventListener("click", () => {
      newSpan.parentElement.remove();
    });
  }
};

addButton.addEventListener("click", () => {
  listItemMake();
});

toDoInput.addEventListener("keydown", (event) => {
  if (event.code === "Enter") {
    listItemMake();
  }
});

for (const removeList of removeLists) {
  removeList.addEventListener("click", () => {
    removeList.parentElement.remove();
  })
}
<h1>ToDo Application</h1>
<div class="container">
  <div class="form-container">
    <input type="text" placeholder="Add New Tasks">
    <button>Add</button>
  </div>
  <div class="list-container">
    <ul>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
    </ul>
  </div>
</div>

CodePudding user response:

Try to move const removeLists and removeList.addEventListener to listItemMake function, so when you add new item const removeLists can include new list item.

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = '(Remove Button)';
    newDiv.append(newSpan);
    listParent.append(newDiv);
  }

  const removeLists = document.querySelectorAll(".remove-li");
  for (const removeList of removeLists) {
  removeList.addEventListener("click", () => {
    removeList.parentElement.remove();
  })
}
};

CodePudding user response:

You don't need the removeLists variable at all (just add event listeners to the static elements). In listItemMake is where the event listener to the removeList button/span should be added:

const toDoInput = document.querySelector("input");
const addButton = document.querySelector("button");
const listParent = document.querySelector("ul");
// const removeLists = document.querySelectorAll(".remove-li");

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = "(Remove Button)";
    newDiv.append(newSpan);
    listParent.append(newDiv);
    newSpan.addEventListener("click", (event) => {
      event.target.parentElement.remove();
    });
  }
};

addButton.addEventListener("click", () => {
  listItemMake();
});

toDoInput.addEventListener("keydown", (event) => {
  if (event.code === "Enter") {
    listItemMake();
  }
});

for (const removeList of document.querySelectorAll(".remove-li")) {
  removeList.addEventListener("click", () => {
    removeList.parentElement.remove();
  });
}
<h1>ToDo Application</h1>
<div class="container">
  <div class="form-container">
    <input type="text" placeholder="Add New Tasks">
    <button>Add</button>
  </div>
  <div class="list-container">
    <ul>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
    </ul>
  </div>
</div>

The first three lines (document.querySelector()) return an Element DOM object. The fourth line (document.querySelectorAll()) returns a static NodeList which can be iterated over similar to an array (but not all the same properties). If you wanted to create an array from a NodeList so that you can use Array methods, you could use [Array.from()][3] by passing in document.querySelector() (just one element) or document.querySelectorAll().

CodePudding user response:

const toDoInput = document.querySelector("input");
const addButton = document.querySelector("button");
const listParent = document.querySelector("ul");

const listItemMake = () => {
  if (toDoInput.value !== "") {
    const newDiv = document.createElement("div");
    newDiv.classList.add("list-item");
    const newListItem = document.createElement("li");
    newListItem.append(toDoInput.value);
    newDiv.append(newListItem);
    toDoInput.value = "";
    const newSpan = document.createElement("span");
    newSpan.classList.add("remove-li");
    newSpan.innerHTML = '(Remove Button)';
    newDiv.append(newSpan);
    listParent.append(newDiv);
  }
  removeEvent()
};

addButton.addEventListener("click", () => {
  listItemMake();
});

toDoInput.addEventListener("keydown", (event) => {
  if (event.code === "Enter") {
    listItemMake();
  }
});

const removeEvent = () => {
const removeLists = document.querySelectorAll(".remove-li");
removeLists.forEach(item=>{
    item.addEventListener("click", () => {
    item.parentElement.remove();
    console.log('removed')
})
})}
<h1>ToDo Application</h1>
<div class="container">
  <div class="form-container">
    <input type="text" placeholder="Add New Tasks">
    <button>Add</button>
  </div>
  <div class="list-container">
    <ul>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
      <div class="list-item">
        <li>Sample List Item</li>
        <span class="remove-li">(Remove Button)</span>
      </div>
    </ul>
  </div>
</div>

  • Related