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>