Hiding A Flash Message After a Time Delay

The flash hash is a great way to provide feedback to your users. Here is a quick tip for hiding the flash message after a period of time if you don’t want to leave it lingering around.

First, add this line to the head of your layout to ensure the prototype and script.aculo.us javascript libraries are loaded:

<%= javascript_include_tag :all %>

Next, add the following to either your layout (recommended), your view templates or a partial depending on your needs. I usually add this to a partial and include the partial in my layouts.

<%- flash.each do |flash_type, message| -%>
  <%= content_tag :div, message, :class => "flash", :id => flash_type %>
  <% content_tag :script, :type => "text/javascript" do %>
    setTimeout("new Effect.Fade('<%= flash_type %>');", 10000);
  <% end %>
<%- end -%>

This will wrap the flash message in a div with class=‘flash’ and id=‘error’, ‘notice’ or ‘warn’ depending on the flash key specified.

The value ‘10000’ is the time in milliseconds before the flash will disappear. In this case, 10 seconds.

This function looks pretty good and little javascript stunts like this can help make your site feel more professional. It’s also worth bearing in mind though, not everybody can see well or read as quickly as others so this may not be suitable for every application.

Update:

As Mitchell has pointed out (see comments below), it may be better to set the flash_type as the div class rather than its id. If there is the possibility that you’ll be showing more than one flash message per page, setting the flash_type as the div id will result in your HTML/XHTML code becoming invalid because the unique identifier will be used more than once per page.

Here is a slightly more complex version of the method shown above that will hide all divs with class “flash” after a time delay, achieving the same effect and also ensuring your code stays valid with more than one flash message!

<%- flash.each do |flash_type, message| -%>
  <%= content_tag :div, message, :class => "flash #{flash_type}" %>
  <% content_tag :script, :type => "text/javascript" do %>
    setTimeout("$$('div.flash').each(function(flash){ flash.hide();})", 10000);
  <% end %>
<%- end -%>

In this example, the div id is not set at all. Instead, each flash div will have class “div” and also class of the type of flash message (“error”, “warning” etc.).

Written by

Photo of Gavin Morrice
Gavin Morrice

Software engineer based in Scotland

Work with me

Need help with some code?

In my free time, I like to help people improve their code and skills on Codementor.
Contact me on Codementor