DEV Community

Cover image for Adding a button inside a clickable element
AndyDziabo
AndyDziabo

Posted on • Updated on

Adding a button inside a clickable element

Introduction

The goal of this task is to add a Delete button to a clickable list item. The trick for me was that the list item itself was a clickable element. When one of the list items is selected, the details of that list item are displayed on another section of the page. The Delete button's job is simply to delete the list item associated with it. The issue is that whenever the Delete button is clicked, it will delete the list item as intended, however because it is a child node of the list item, the list item's click event is also triggered.

The Code

Getting into the code, the first section is a function that builds the list of films.

Image description

The list is made using a function that utilizes a for...in statement to iterate through the film list object. It creates a new list item and populates that list item with the appropriate info for that individual film. It also creates a button with a click event that calls another function which carries out the deleting of the list item. The button is then appended as a child of the list item and the list item appended to the unordered list.

Now that we have a complete list of the films, we add an event listener to the film list. The event listener calls a function that will display the details of the selected film.

Image description

Building the Delete button

The next step is to make the Delete button functionable. The button already returns an event response with the onclick attribute, which is set to call the deleteFilm function.

Image description

The deleteFilm function takes the id of the selected film and passes it to a fetch DELETE request. When the fetch DELETE request returns, it calls the getFilms function and repopulates the film list to reflect the change. The issue is that as the code is written now, when the Delete button is clicked the associated film is deleted as desired, but then we get an error.

This error happens because when the Delete button is clicked it functions as desired, but the Delete button is a child of the list item it's associated with. This means that when the Delete button is clicked, not only is it's event handler triggered, the event handler for the list item is also triggered. This calls the function that populates the details of the film. The error happens because it is trying to display the details of the film that has been deleted and the info no longer exists.

Now I'm sure this issue could be handled with some conditional statements that look at each of the events that are triggered and use some attributes to only allow the desired event to fire. Before doing all that, I wanted to see if there was a simpler solution, so I took to Google to see. On the W3 schools website I found the solution I was looking for - the stopPropagation() method. Here is the definition and usage from the W3 schools website:

Image description

This method is exactly what we are looking for and simply adding this one line to the code resolves the error we are getting. It allows the delete function to run, but then blocks the event of the parent node (the list item) from being triggered. Here is the delete function with stopPropagation() method added.

Image description

We now have a functioning list in which we can select the film that we wish to see the details for, as well as delete films we no longer want on the list.




https://www.w3schools.com/jsref/event_stoppropagation.asp

Top comments (0)