I'm using the Devise gem and I just would like to show a successful message when someone ask for a new password (if forgotten). Currently, when submitted, the button redirects to sign_in without any message.
Thank you
Rather than using the flash and trying to work out how Devise does it's thing (not for the faint-hearted) by extending its controllers, how about checking the referrer, and displaying a message in the view if it matches your 'remind me of my password' path?
In the view:
<% if request.env['HTTP_REFERER'] == "/give/me/a/new/password" %>
<h2>Your password stuff is all good now.</h2>
<% end %>
flash[:success] = "Something Something"
Devise rolls out it's own alert messages (and they can be edited in the config/locales/devise.en.yml and written for other languages), you just need to catch them.
One way is to add a layout/_messages partial:
<% flash.each do |name, msg| %>
<% if msg.is_a?(String) %>
<div class="alert alert-<%= name %>">
<a class="close" data-dismiss="alert">×</a>
<%= content_tag :div, msg, :id => "flash_#{name}" %>
</div>
<% end %>
<% end %>
and render it in application.html.erb:
<%= render 'layouts/messages' %>
This has the benefit of catching all (devise and other) messages and playing nicely with bootstrap alert classes (if you use were using bootstrap).
.
Or if you are using slim:
- flash.each do |name, msg|
- if msg.is_a?(String)
div class="alert alert-#{name}"
a class="close" data-dismiss="alert"
| ×
= content_tag :div, msg, :id => "flash_#{name}"
= render 'layouts/messages'
.
Devise uses the rails standard :notice rather than :success but a you can add the success (green) styling to your css/scss (e.g. to bootstrap_and_overriders.css.scss):
.alert-alert {
#extend .alert-error
}
.alert-notice {
#extend .alert-success
}
Related
I have already imported bootstrap and I'm using the 'bootstrap-sass' gem and devise gem. The problem is My rails app shows the the right message like if am signed in and i try to sign up it shows the message 'You are already signed in.' but without the color around the message like yellow or red or any color.
<div class="container">
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, class: "alert alert-#{name}") %>
<% end %>
</div>
When I inspect the element in chrome after it rendered I get 'class="alert alert-alert"'
In my code above the "alert alert-#{name}" the name is the key which should change to info, success, or warning or danger. but it keeps changing to alert which bootstrap doesn't have. How can i fix this?
You can fix this by setting your flash message in your controller as flash[:success], flash[:info], flash[:warning] or flash[:danger], as opposed to flash[:alert].
For Devise, you will need to copy the Devise controllers into your Rails application to override these values. Alternatively, you can display the Bootstrap alerts manually if flash[:notice] or flash[:alert] are set:
<% if flash[:notice] %>
<div class="alert alert-info">
<%= flash[:notice] %>
</div>
<% end %>
<% if flash[:alert] %>
<div class="alert alert-danger">
<%= flash[:alert] %>
</div>
<% end %>
I am having problem in bootstrap flash message . I have to change color for some text in flash message.
Controller
redirect_to complaints_path, notice: "Complaint was successfully created & Your Complaint Reference Id is #{#complaint.complaint_id}"
I have change color of the #complaint/complaint_id
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "danger" %>">
<span class="close" data-dismiss="alert">×</span>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
</div>
<% end %>
It will display success message in green color. but i have change complaint_id alone red color..
Please help me..
You can create an helper to deal with flash messages:
module ApplicationHelper
def bootstrap_class_for flash_type
{ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }[flash_type] || flash_type.to_s
end
def flash_messages(opts = {})
flash.each do |msg_type, message|
concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} fade in") do
concat content_tag(:button, 'x', class: "close", data: { dismiss: 'alert' })
concat message
end)
end
nil
end
end
Then in your application.html.erb layout use them:
<body>
<div class="container">
<%= flash_messages %>
<%= yield %>
</div><!-- /container -->
</body>
If you don't want this DRY approach, you can adapt it to your needs.
I'm not sure why this is happening, but when I submit a form successfully in my rails app it is adding a div class of an error to my successful flash message. I'm using this code for my flash messages:
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name == :notice ? "success" : "error" %>">
<a class="close" data-dismiss="alert">×</a>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
</div>
<% end %>
That's exactly what Ryan Bates suggests doing in this rails cast:
http://railscasts.com/episodes/329-more-on-twitter-bootstrap?view=asciicast
What is wrong with that code? It works fine if I simply do this:
<% flash.each do |name, msg| %>
<div class="alert alert-<%= name %>">
<a class="close" data-dismiss="alert">×</a>
<%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
</div>
<% end %>
But that doesn't seem to be the right way to do this. I don't understand why the code suggested in the railscast doesn't work.
You may put a string 'notice' instead of a symbol :notice when you created the flash message in your controller. Try adding these lines in your application.html.haml to see what you get from your flash messages
- if Rails.env.development?
= debug(params)
= debug(flash) unless flash.empty?
As far as I remember, flash sometimes contain empty elements. Check if you have something in flash before iteration.
How can I pass an optional parameter to the flash message?
I'm using Twitter Bootstrap alert messages, and I want to add the ".alert-block" css class to the message, based on a parameter or something I set in the controller.
Thanks.
This is my solution:
flash[:success_block] = "<h4>Bla blah.</h4> <p>Blah blah.</p>"
<% flash.each do |name, msg| %>
<% block = true if name.to_s.split('_').last == 'block' %>
<% name = name.to_s.split('_').first if block %>
<div class="alert fade in alert-<%= name %> <%= 'alert-block' if block %>">
<a class="close" data-dismiss="alert">×</a>
<%= msg.html_safe %>
</div>
<% end %>
The best practice is to map the flash message on the different alert types that twitter bootstrap provides (ie flash[:info] to .alert-info, flash[:success to alert-success]...)
You can't pass parameters to flash variables, but you can access instance variables of a controller, or even methods by using helper_method from your views/layouts.
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 try again.</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?
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">
×
<%= value %>
</div>
<% end %>
</div>
Differences:
Does not loop through different error levels each time it is called.
Instead loops through the flash hash if the hash contains messages (following the
approach in Michael Hartl's Rails Tutorial).
Does not use the <p> tag, no longer required in Bootstrap 2.0.
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.
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">
×
<%= 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/
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">×</button>
<%= value %>
</div>
<% end %>
</div>
Differences:
Change Bootstrap classes for error and alert.
Add .alert-dismissable and change the code for close button.
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 %>
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
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 %>">
×
<%= value %>
</div>
<% end %>
This makes a ApplicationHelper#flash_class(level) obsolete. It hardcodes styling into the application, which smells. Styling belongs into stylesheets.
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 %>
...
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 %>