How do you display your Flash messages in your layouts?

Just curious how others render flash[:notice] and others in their views… Most Rails devs I see do something like this (overly simplified example)

(application.html.erb)

<% if flash[:notice].blaink? %>

<%= flash[:notice] %>
<% end %>
<%=yield %>

Of course, this puts the flash above the main page content (your views.) I’ve noticed a few times that the notifications aren’t noticeable, no matter how much you style them. So, my question is, what do others do? Place the flash output in every view rather than in the layouts? Do you use JavaScript to move the div to a new location in the DOM?

Thanks for your input! It should be neat to see different solutions.

Here's a nice trick I use. I have the following in application_helper.rb:

[code]     def flash_div(*keys)       visual_effect(:fade, :flashdiv)       keys.collect { |key| content_tag(:div, flash[key], :class => "flash #{key}") if flash[key] }.join     end [/code]

Then, in my master layout, for the main section, I have:

[code]     <div id="main">       <div id="main_padding">           <%= flash_div :warning, :notice, :error %>           <%= yield %>       </div>     </div> [/code]

Then I style it using:

[code] #flashdiv {   float:left;   margin-left:20px;   margin-top:10px; } .flash{   padding:10px;   margin-bottom: 1em; } .warning{   background:#f3b9ba;   border: 1px solid #d8aeaf; } .notice{   background-color:#c8f4ba;   border: 1px solid #b0d6a3; } .notice strong{   background-color:#bee4b2;   padding: 2px; } .error{   background:#ff0000;   color: #fff; } [/code]

This works very well... it gives me a nice, style flash that is color- coded for the type (warning, error, notice). Also, it fades away and the DOM element is actually removed.

Enjoy!

-Danimal

I just style a #notice div with CSS, and then in my application layout file, right above yield, I have:

<%= "<div id='notice'>#{flash[:notice]}</div>" if flash[:notice] %>

And then to make it fade out after 5 seconds:

<% if flash[:notice] %>    <script type="text/javascript">       new Effect.Fade('notice', { delay: 5 });    </script> <% end %>

The styling works but the fading doesn't. I like the solution by AtsoK, but I haven't tried it yet. I did [body onload=.. to make the error pulsate, and it seems not to be a problem when the id isn't found (when there is no error in flash).

The visual_effect call just generates javascript as a string. It would need [script] tag to execute. Or an onsomething="code" thing.

And what element has the 'flashdiv' id ?

And don't we need a 'render :update' or something similar to call an rjs or an action for this happen?

In any case, I'm not sure I want my messages to fade away, people will turn their heads and come back and it's gone...

Still, it's not bad looking.

Did it fade for you? What browser were you using?

F

The fading would be implemented by a javascript method…

There is a post on this at: http://blog.andreasaderhold.com/2006/07/rails-notifications

My solution is to use a div across the bottom of the screen, built into the layout.

The div is attached to the bottom of the window by using fixed.

As others have done, i use styling to set the color of the div to different colors for different messages.

The nice thing about this approach is that it if you need to be able to get to fields underneath, you can arrange to leave some blank at the bottom of the main screen so that it can be scrolled up, putting any covered fields above the div.

Also, to be able to see anything below the div, I use a hover transparent style.

Also, the div can expand upwards so that multiple messages can be displayed. If the div is in the way, I have made it clickable with a remote call to the main page which simply replaces the div content with an empty string.

I populate the contents of the div with a partial called all_messages. At the moment, this partial gets its content from a helper called all_messages. This helper combines flash and error messages. Instead of using the standard error_messages_for helper. What I do is set a variable @errors_for in the view, which the helper then uses to set the content for the partial that creates the div at the bottom of the screen.

It sounds a bit complex, but it works like a dream. All I ever have to remember to do is set the @errors_for with the models that I want errors for, just the same as the error_messages_for helper.

Finally, I can also populate it from an ajax call by including a page.replace_html 'prompt', :partial=>'layouts/all_messages' which will also ensure any flash or error messages are displayed from an ajax call.

I think it can be improved by use of content for, but havn't got round to thinking it through quite yet.

May be of some help. Tonypm

Tonypm,

I'm trying to accomplish something similar with my application right now, but I seem to be missing some vital step to bridge the final gap between "including a page.replace_html 'prompt', :partial=>'layouts/ all_messages' " and the rest of it. Do you have a global way of rendering the partial or do you include code in all your controller actions to make that happen?

tmo26

I was thinking about that point just the other day. At the moment, I have to explicitly put that replace_html/partial line in all my actions where I may be needing a flash or error message. It would be nice if that got included automatically, but I havnt given it any real thought. I guess it would be a matter of introducing something into the render method, but that could be messy. I'll give it a bit more thought in the near future and if I do come up with anything, I'll let you know - or if anyone else has any ideas they would be welcome.

Thanks Tonypm

I've used a solution similar to AstoK:

<%= content_tag(:div, flash[:notice], :class => 'notice') if flash[:notice] %>

best. mike

AtsoK wrote:

I just style a #notice div with CSS, and then in my application layout file, right above yield, I have:

<%= "<div id='notice'>#{flash[:notice]}</div>" if flash[:notice] %>

And then to make it fade out after 5 seconds:

<% if flash[:notice] %>    <script type="text/javascript">       new Effect.Fade('notice', { delay: 5 });    </script> <% end %>

Really cool trick. It's exactly what I was looking for. Do you have any idea how to combine visual_effects? The doc for scriptaculous is broken at github, it misses the demo page.