10

im using twitters bootstrap alert messages. in my application.html.erb I have...

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

normally when I want to do a flash message, I would write something like

flash[:success] = "Profile updated"

however im not sure how I can give the devise error messages a key and value pair. I looked into the devise.en.yml but can't seem to associate the message with a key ie :success, :error etc. could someone help? thanks!

Lain
  • 2,166
  • 4
  • 23
  • 47
Sasha
  • 3,281
  • 7
  • 34
  • 52

4 Answers4

37

For anyone coming across this that does not know how to override the devise error messages with bootstrap.

  1. Create file named:

/app/helpers/devise_helper.rb

  1. Add the following code:
module DeviseHelper
 def devise_error_messages!
  return '' if resource.errors.empty?

   messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join
   sentence = I18n.t('errors.messages.not_saved',
   count: resource.errors.count,
   resource: resource.class.model_name.human.downcase)

   html = <<-HTML
   <div class="alert alert-error alert-block"> <button type="button"
    class="close" data-dismiss="alert">x</button>
    <h4>#{sentence}</h4>
    #{messages}
   </div>
   HTML

   html.html_safe
 end
end
Francois
  • 10,465
  • 4
  • 53
  • 64
  • 1
    Very cool, thanks! This was my question that brought me here. – Laszlo T Dec 23 '13 at 00:11
  • 8
    Please note that depending on the version of Bootstrap you're using you might have to use alert-danger instead of alert-error. So if you try Francois' suggestion verbatim and get a white background instead of pink/red, that might be the reason. – Antonio Cangiano Dec 20 '14 at 17:35
8

This is how i do it

<% flash.each do |key, value| %>
<div class="message">
   <div class="alert-message <%= key %> fade in">
    <a class="close" href="#">&times</a>
    <center><strong><%= value %></strong></center>
  </div>
</div>
<% end %>
ahmet
  • 4,955
  • 11
  • 39
  • 64
  • oh the messages display correctly, however everything appears as a yellow box. i want to be able to give it a green box, like a success version. normally i would do it by adding flash[:success] or if i wanted a red box flash[:error] – Sasha Apr 20 '12 at 20:23
  • i got it. all you have to do is override the controller where the messages are normally sent. – Sasha Apr 20 '12 at 20:30
2

The simplest solution I've found is to use a common partial for all flash messages while checking for :notice and :alert to replace with the necessary bootstrap class.

So make /views/shared/_alerts.html.erb like this -

<% flash.each do |message_type, message| %>
 <div class="alert alert-<%= flash_class_name(message_type) %> alert-dismissable">
  <span><%= message %></span>
  <button type="button" class="close" data-dismiss="alert" aria-label="Close">
    <span aria-hidden="true">&times;</span>
  </button>
 </div>
<% end %>

Add a helper method (I've added it to the application helper) like this -

def flash_class_name(name)
  case name
  when "notice" then "success"
  when "alert"  then "danger"
  else name
  end
end

Include _alerts.html.erb in the application layout (or the parent layout for your application).

That's it!

nphadke
  • 502
  • 5
  • 8
0

Thing is that devise_error_messages! by itself wraps the data into div with class='alert', so the form will have 2 nested divs with the same class. Pressing the x button will close nested div, leaving empty div styled as alert. To avoid this you can omit the div inside helper return value as following:

module DeviseHelper
  def devise_error_messages!
    return '' if resource.errors.empty?

    messages = resource.errors.full_messages.map { |msg| content_tag(:li, msg) }.join

    html = <<-HTML
      <button type="button" class="close" data-dismiss="alert">x</button>
      #{messages}
    HTML

    html.html_safe
  end
end
zmii
  • 4,123
  • 3
  • 40
  • 64