27

I am integrating twitter bootstrap css into my application. Going along just fine,but I don't know how to customize the css and wrappers for my flash messages.

I would like my flash messages to be formatted with the default Bootstrap classes:

    <div class="alert-message error">
      <a class="close" href="#">×</a>
      <p><strong>Oh snap!</strong> Change this and that and <a href="#">try again</a>.</p>
    </div>

Currently I output my flash messages with:

<% flash.each do |name, msg| %>
    <%= content_tag :div, msg, :id => "flash_#{name}" %>
<% end %>

Is there an easy way to run a little switch that would make :notification or other rails flash messages map to the classes in bootcamp, like info?

Rapture
  • 1,876
  • 10
  • 23
  • 42
  • 1
    try to see if this helps you http://stackoverflow.com/questions/2824271/how-to-customize-flash-message-based-on-success-or-failure-with-inherited-resour – Pabluez Jan 04 '12 at 15:37

8 Answers8

55

My answer for Bootstrap 2.0 starts from the helpful answer by @Railslerner but uses different code in the partial.

app/helpers/application_helper.rb (same as @Railslerner's answer)

module ApplicationHelper
  def flash_class(level)
    case level.to_sym
    when :notice then "alert alert-info"
    when :success then "alert alert-success"
    when :error then "alert alert-error"
    when :alert then "alert alert-error"
    end
  end
end

Somewhere in app/views/layouts/application.html.erb:

<%= render 'layouts/flash_messages' %>

app/views/layouts/_flash_messages.html.erb

<div>
  <% flash.each do |key, value| %>
    <div class="<%= flash_class(key) %> fade in">
      <a href="#" data-dismiss="alert" class="close">×</a>
      <%= value %>
    </div>
  <% end %>
</div>

Differences:

Remember to include bootstrap-alert.js so the fade and close functionality will work. If you're using the bootstap-sass gem, add this line to app/assets/javascripts/application.js:

//= require bootstrap-alert


Update 8/9/2012: Folders updated. I actually put everything except the helper under app/views/layouts since flash_messages is only used in app/views/layouts/application.html.erb.

Update 6/5/2015: After updating to Rails 4.2, I discovered that level was (at least sometimes) coming in as a String and failing to match the case statement in the ApplicationHelper. Changed that to level.to_sym.

Mark Berry
  • 17,843
  • 4
  • 58
  • 88
  • @andkjaer, so flash is Nil? I'm not sure where the flash is instantiated. Does the flash work without the Bootstrap customizations, e.g. if you follow [Michael Hartl's instructions](http://ruby.railstutorial.org/chapters/sign-up#sec:the_flash)? – Mark Berry Mar 10 '12 at 02:11
  • Thanks! Works well. Any ideas on how to use this code when we are making an AJAX call to the conroller? – rohitmishra Sep 17 '12 at 15:14
  • Sorry I haven't gotten into Ajax yet. Maybe others will chime in. – Mark Berry Sep 18 '12 at 02:10
  • Now in Bootstrap 4 need modify "fade in" for "fade show" – Robin Gomez Aug 25 '17 at 20:00
8

Here's my answer with Bootstrap 2.0.0

app/helpers/application_helper.rb

module ApplicationHelper
  def flash_class(level)
    case level
    when :notice then "alert alert-info"
    when :success then "alert alert-success"
    when :error then "alert alert-error"
    when :alert then "alert alert-error"
    end
  end
end

app/views/shared/_flash_messages.html.erb

<% [:notice, :error, :alert].each do |level| %>
   <% unless flash[level].blank? %>
     <div class="<%= flash_class(level) %> fade in">
      <a href="#" data-dismiss="alert" class="close">×</a>
       <%= content_tag :p, flash[level] %>
     </div>
   <% end %>
<% end %>

This gives you the fade out when closed and close button. If you were using HAML, checkout this guys post: http://ruby.zigzo.com/2011/10/02/flash-messages-twitters-bootstrap-css-framework/

LearningRoR
  • 26,582
  • 22
  • 85
  • 150
6

I am adding a new answer for Bootstrap 3.0 based on Mark Berry's answer. The Bootstrap CSS for alerts is at http://getbootstrap.com/components/#alerts

app/helpers/application_helper.rb

module ApplicationHelper
  def flash_class(level)
    case level
    when :notice then "alert-info"
    when :success then "alert-success"
    when :error then "alert-danger"
    when :alert then "alert-warning"
    end
  end
end

app/views/layouts/_flash_messages.html.erb

<div>
  <% flash.each do |key, value| %>
    <div class="alert alert-dismissable <%= flash_class(key) %> fade in">
       <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
      <%= value %>
    </div>
  <% end %>
</div>

Differences:

  • Change Bootstrap classes for error and alert.
  • Add .alert-dismissable and change the code for close button.
rohitmishra
  • 8,739
  • 7
  • 33
  • 34
2

Bootstrap 3 class names (adjusted from Mark Berry's answer):

def flash_class(level)
  case level
    when :notice then "alert alert-info"
    when :success then "alert alert-success"
    when :error then "alert alert-danger"
    when :alert then "alert alert-warning"
  end
end
Judd Lyon
  • 538
  • 1
  • 4
  • 11
2

Try this:

application_helper.rb

def flash_class(level)
  case level
    when :notice then "info"
    when :error then "error"
    when :alert then "warning"
  end
end

and then

<% [:notice, :error, :alert].each do |level| %>
  <% unless flash[level].blank? %>
    <div data-alert="alert" class="alert-message <%= flash_class(level) %> fade in">
      <a class="close" href="#">×</a>
      <%= content_tag :p, flash[level] %>
    </div>
  <% end %>
<% end %>
Zoran Kikic
  • 247
  • 3
  • 7
1

I would suggest adding classes for the different notification levels used in rails:

.alert-notice {
    background-color: #f2dede;
    border-color: #eed3d7;
    color: #b94a48; }

etc.

and use them according to the examples from twitter bootstrap:

<% flash.each do |key, value| %>
    <div class="alert alert-<%= key %>">
        <a href="#" data-dismiss="alert" class="close">×</a>
        <%= value %>
    </div>
<% end %>

This makes a ApplicationHelper#flash_class(level) obsolete. It hardcodes styling into the application, which smells. Styling belongs into stylesheets.

tvw
  • 316
  • 3
  • 4
0

If you want to completely alter the styling of the flash message--for example, if you don't want the message to fade, you can even do something like this:

In your controller:

flash[:order_error] = "This is an important error that shouldn't fade!"

Then compare the flash key to show the appropriate styling (with to_sym):

<% flash.each do |key, msg| %>
  <% if key == 'order_error'.to_sym %>
    <div class="error" id="newErrorStyle"><%= msg %></div>
  <% else %>
    <div class="<%= key %>" id="flash-<%= key %>"><%= msg %></div>
    <% content_tag :script, :type => "text/javascript" do -%>
      setTimeout("new Effect.Fade('flash-<%= key %>');", 8000);
    <% end %>
  <% end %>
<% end %>
Dawn Green
  • 483
  • 4
  • 16
0

It's not the ideal solution, but assuming you only ever use 'notice' or 'error' flash messages, you can use this:

...
<% content_tag :div, :id => "flash_#{name}", :class => "alert-message #{name == "notice" ? "success" : name}" do %>
...
Jules Copeland
  • 1,690
  • 17
  • 22