Last week I was working on a small to-do list app as a weekly project for a BootCamp for web developers that I’m enrolled in. The app is built with vanilla JavaScript, HTML/CSS for the UI. Although it is a “must” to have a to-do list app in front-end developers’ portfolio I’d never actually done it prior to this project and now I can see why people are saying how crucial it is for applying your skills into practice.
The features of the app were clear and seemingly simple:
- Display list items dynamically
- Save the data in the local storage
- User should be able to add/remove items to/from the list
- User should be able to edit the list items
As you can see in the code above I used <input type="text">
to display the description(name) of each task. The reason I chose to use it is to be able to edit the description and listen to the change event.
Throughout the process of building the app, I didn't really face any issues until I started working with focusin
and focusout
events alongside click events.
This was my thought process making this feature:
- Attach
focusin
event listener to the input field - Apply styles (by adding classes)
- Hide the options button and display the remove button (
display: none
anddisplay: block
). - On
focusout
event get everything back to the way it was - Attach the click event listener to the remove buttons
- Remove the clicked item (match the
data-index
attribute with theindex
property of the item object in our list) then store and display the new list
The edit mode was working as expected. As you can see the styles get applied and the button gets displayed when I go to the edit mode. And vice versa when I go out of focus of the input (click anywhere else in the document) the list items go to the initial state.
Now this is where the problem takes place
As I said before we are setting our delete button to display: none
on focusout
which removes it from the DOM. When we try to click on that button the focusout
event will fire and remove the element leaving us no chance of clicking on it and therefore deleting the list item. So how do we go around this bug?
After a lot of researching and testing, I figured out that I need to find a way to skip the step of hiding the remove button when it gets clicked.
If it was a click event we know that we could use ClickEvent.target to get the element that we click on. Focusout
event is different though. It does not listen to clicks but it gets triggered whenever we go out of focus of the element the event is attached to.
Logging the event property I noticed the relatedTarget
key and its value being the element that we click on.
When we click on a blank space on the document we get null
as a value, but if it's an element the value is the element that we click on.
From here we add our check to see if the clicked item contains the "btn-delete" class and we do nothing if it does(return
), otherwise we just hide the button. Here's what our event listener would look like in the end.
Viola! The bug has been fixed. Our to-do list app is now looking much better and cleaner and we can do whatever we want with it.
Top comments (0)