josefrichter
Flash message to disappear after 5 seconds?
Is there a way to have a flash message disappear (fade out) after a few seconds, please? Can’t find anything in docs nor on internets. Feels like this could be easy in LiveView, maybe I’m just missing the obvious. Thank you.
Marked As Solved
sfusato
You can achieve that with something like this:
Send a message to self when you use put_flash
Process.send_after(self(), :clear_flash, 5000)
Then, in handle_info:
def handle_info(:clear_flash, socket) do
{:noreply, clear_flash(socket)}
end
Also Liked
davidmac
Here is a solution using hooks. It hides info flash messages after 10 seconds and leaves error flash messages open until the user closes them.
Create a file called hooks.js for your hooks.
// assets/js/hooks.js
let Hooks = {}
Hooks.HideFlash = {
mounted() {
setTimeout(() => {
this.pushEvent("lv:clear-flash", { key: this.el.dataset.key })
this.el.style.display = "none"
}, 10000)
}
}
export default Hooks
Don’t forget to add your hooks to your liveview socket.
// assets/js/app.js
// ...
let liveSocket = new LiveSocket("/live", Socket, {
longPollFallbackMs: 2500,
params: {_csrf_token: csrfToken},
hooks: Hooks,
})
// ...
Add the hook to the flash component.
# core_components.ex
def flash(assigns) do
assigns = assign_new(assigns, :id, fn -> "flash-#{assigns.kind}" end)
~H"""
<div
:if={msg = render_slot(@inner_block) || Phoenix.Flash.get(@flash, @kind)}
id={@id}
phx-hook={@kind == :info && "HideFlash"}
phx-click={JS.push("lv:clear-flash", value: %{key: @kind}) |> hide("##{@id}")}
role="alert"
class={[
"fixed top-2 right-2 mx-2 min-w-80 max-w-xl z-50 rounded-lg p-3 ring-1",
@kind == :info && "bg-emerald-50 text-emerald-800 ring-emerald-500 fill-cyan-900",
@kind == :error && "bg-rose-50 text-rose-900 shadow-md ring-rose-500 fill-rose-900"
]}
{@rest}
>
<p :if={@title} class="flex items-center gap-1.5 text-sm font-semibold leading-6">
<.icon :if={@kind == :info} name="hero-information-circle-mini" class="h-4 w-4" />
<.icon :if={@kind == :error} name="hero-exclamation-circle-mini" class="h-4 w-4" />
<%= @title %>
</p>
<pre class="mt-2 text-sm leading-5 whitespace-pre-wrap"><%= msg %></pre>
<button type="button" class="group absolute top-1 right-1 p-2" aria-label={gettext("close")}>
<.icon name="hero-x-mark-solid" class="h-5 w-5 opacity-40 group-hover:opacity-70" />
</button>
</div>
"""
end
LostKobrakai
Copy from what I wrote on bluesky.
A simple solution can be:
Putting the following on the <.flash> core component
phx-mounted={JS.dispatch("myapp:auto-clear", detail: %{timeout: 5000, attr: "phx-click"})}
and this JS in app.js
window.addEventListener("myapp:auto-clear", (e) => {
let el = e.target;
setTimeout(() => liveSocket.execJS(el, el.getAttribute(e.detail.attr)), e.detail.timeout);
});
josefrichter
Bingo! I’ve combined both of your solutions, and tweaked it a bit. I kept push_redirect rather than push_patch as I was “returning” to index and with push_patch my index of items was not updated.
My workaround is that I actually put the Process.send_after into my mount function, because that’s where I always get back to – so if there’s any new flash message displayed, it gets cleared after 5s. Not sure it’s super robust solution, but this way I need the clear function in one place only, and it works nicely.
And I applied the css animation to nicely fade out the flash, no need for javascript, nor desirable for this simple animation, I think.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









