I’m working on a simple JavaScript project where I’m building a todo list. The goal is to allow users to add new todo items and delete them by clicking a trash icon. However, I’m having trouble getting the delete functionality to work as expected.
What I Tried:
Adding Event Listener: I attached an event listener directly to the trash icon (<i>
) inside the addNewTodo()
function. This listener is supposed to trigger when the icon is clicked and then remove the corresponding <li>
element from the DOM.
Logging the Click Event: I added a console.log statement inside the event listener to verify that the click event is firing. This log message isn’t working because of the click event isn’t firing.
Removing the Todo Item: Within the same event listener, I called the remove()
method on the parent <li>
element (newTodoLi()
) to remove the todo item from the list. My expectation was that clicking the trash icon would delete the corresponding todo item.
What I Expected:
I expected that each time I clicked on a trash icon next to a todo item, the item would be immediately removed from the list without any issues. Since the event listener seemed to be firing correctly, I anticipated that calling remove()
on the parent <li>
would reliably delete the item.
let inputElem = document.querySelector("input");
let addTodoForm = document.querySelector(".add");
let todoUlElem = document.querySelector(".todos");
function addNewTodo(newTodoValue) {
// Create the new li element
let newTodoLi = document.createElement("li");
newTodoLi.className =
"list-group-item d-flex justify-content-between align-items-center";
// Create the span for the todo title
let newTodoTitleSpan = document.createElement("span");
newTodoTitleSpan.innerHTML = newTodoValue;
// Create the trash icon element
let newTodoTrash = document.createElement("i");
newTodoTrash.className = "fa fa-trash delete";
// Append the title span and trash icon to the new li element
newTodoLi.append(newTodoTitleSpan, newTodoTrash);
// Append the new li element to the ul element
todoUlElem.append(newTodoLi);
// Add an event listener to the trash icon
newTodoTrash.addEventListener("click", (e) => {
console.log("clicked delete icon");
// You can add more functionality here, like removing the todo item
// newTodoLi.remove();
});
}
// Prevent the default form submission
addTodoForm.addEventListener("submit", (e) => {
e.preventDefault();
});
// Add a new todo item when Enter key is pressed
inputElem.addEventListener("keydown", (e) => {
let newTodoValue = e.target.value.trim();
if (e.keyCode === 13) {
inputElem.value = "";
if (newTodoValue) {
addNewTodo(newTodoValue);
}
}
});
body {
background: #353f5b;
}
.container {
max-width: 400px;
margin-top: 90px;
}
.search i {
position: absolute;
}
.search {
position: relative;
}
.icon {
padding: 10px;
left: 0;
}
.input-field {
text-align: center;
}
input[type="text"],
input[type="text"]:focus {
color: #fff;
border: none;
background: rgba(0, 0, 0, 0.3);
max-width: 400px;
}
.todos li {
background: #423a6f;
}
.delete {
cursor: pointer;
}
.filtered {
display: none !important;
}
span {
color: #fff;
}
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/css/all.min.css" integrity="sha512-q3eWabyZPc1XTCmF+8/LuE1ozpg5xxn7iO89yfSOd5/oKvyqLngoNGsx8jq92Y8eXJ/IRxQbEC+FGSYxtk2oiw==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<!-- originally=> <script src="FontAwesome5/all.min.js"></script> -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.9.0/js/all.min.js" integrity="sha512-LW9+kKj/cBGHqnI4ok24dUWNR/e8sUD8RLzak1mNw5Ja2JYCmTXJTF5VpgFSw+VoBfpMvPScCo2DnKTIUjrzYw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div class="container">
<ul class="list-group todos mx-auto text-light"></ul>
<form class="add text-center my-4" autocomplete="off">
<label class="text-light"> Add New Todo... </label>
<input type="text" class="form-control m-auto" name="add" />
</form>
</div>
I have bring all the codes to make easier the problem for you
2
Answers
Your issue is that the
<i class="fa fa-trash delete">
delete button is being replaced with an<svg>
element in the DOM. The original handler is no longer applicable.Instead, you should attach a delegation listener to the
<ul>
and check to see if you clicked inside the<svg>
.A more streamlined approach
You can add a
click
handler to the todo list element, and delegate clicks down to the removal button.See the example below:
First of All -> remove
<script src="FontAwesome5/all.min.js"></script>
because it replace your:
<i class="fa fa-trash delete"></i>
by a
<svg>
element.Also there some JS facility you should have to know:
HTML templates : https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template
Event delegation = ( Event_bubbling +
.matches()
method )–> What is event delegation, and how does it work?
on you code: