Screencast

Autoclear Flash message

1. Autoclear Flash message

flash liveview

In this video, we're going to enhance the user experience by implementing an auto-clear functionality for flash messages. Flash messages are typically used to provide feedback to users after actions like form submissions, but they can sometimes overstay their welcome, becoming distracting or even annoying. The goal is to automatically clear these messages after a set period, creating a cleaner and more streamlined user experience.

The flash component we're working with resides in the core components module, which contains all the components included with a new Phoenix project. Our objective is to modify this flash component so that it triggers a JavaScript function automatically after it appears.

Currently, the flash message can be closed manually by clicking on it, thanks to a Phoenix DOM binding. We’ll build on this by triggering that action automatically after a few seconds. To do this, we'll add a line of code that will execute as soon as the component mounts, leveraging another Phoenix binding to dispatch a JavaScript event.

This requires only a small JavaScript snippet, which I'll add to the main application JavaScript file. This snippet sets up an event listener for a custom event called "flash:autoclear," matching the name we used in the component. The key part here is the `execJS` function, which is a built-in Phoenix feature designed to handle these specific JavaScript events.

Once the component mounts and the event is triggered, a timeout will wait for two seconds before executing the Phoenix click event, effectively clearing the flash message.

Now that the code changes are in place, let's test them. I'll edit one of our records and submit the form. Notice how the flash message appears to confirm our action? Perfect. Now, watch for a couple of seconds... and there it goes, disappearing on its own!

With this improvement, users can continue their workflow without the distraction of lingering flash messages.

lib/boilerplate_web/components/core_components.ex

phx-mounted={JS.dispatch("flash:autoclear", to: "##{@id}")}

assets/js/app.js

window.addEventListener("flash:autoclear", (event) => {
  const el = event.target

  setTimeout(() => {
    liveSocket.execJS(el, el.getAttribute("phx-click"))
  }, 2000)
})