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
focusout events alongside click events.
This was my thought process making this feature:
focusinevent listener to the input field
- Apply styles (by adding classes)
- Hide the options button and display the remove button (
focusoutevent get everything back to the way it was
- Attach the click event listener to the remove buttons
- Remove the clicked item (match the
data-indexattribute with the
indexproperty 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.
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.
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.