How to modify bootstrap flash message in rails 4 - ruby-on-rails

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.

Related

Rails/Bootstrap - Flash notice :success is now red and not green?

I've been trying to search for an answer on here but I can't find anything that works. I have implemented a :success and :danger flash notice to my rails app. It WAS working completely fine, i.e :success was green and :danger was red, with a close button and all, BUT since adding some mailer files my :success is now showing up red??
application.html.erb excerpt:
<body>
<div class="container">
<% flash.each do |key, value| %>
<%= content_tag :div, class: "alert alert-#{key == 'notice ? 'success' : 'danger'}" do %>
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<%= value %>
<% end %>
<% end %>
<%= yield %>
</div>
</body>
contact_mailer.rb
class ContactMailer < ActionMailer::Base
default to: 'justindavidson23#gmail.com'
def contact_email(name, phone, email, event_type, body)
#name = name
#phone = phone
#email = email
#event = event_type
#body = body
mail(from: email, subject: 'Contact Form Message').deliver
end
end
contacts_controller.rb
class ContactsController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(contact_params)
if #contact.save
name = params[:contact][:name]
phone = params[:contact][:phone]
email = params[:contact][:email]
event = params[:contact][:event_type]
body = params[:contact][:comments]
ContactMailer.contact_email(name, phone, email, event, body).deliver
flash[:success] = 'Message Sent.'
redirect_to new_contact_path
else
flash[:danger] = 'Error occurred, messgage not sent.'
redirect_to new_contact_path
end
end
end
private
def contact_params
params.require(:contact).permit(:name, :phone, :email, :event_type, :comments)
end
and, contact_email.html.erb
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<p>New Message from Hoot and Holla's Contact form, from <%= "#{#name}, #{#email}" %></p>
<p><%= #phone %></p>
<p><%= #event %></p>
<p><%= #body %></p>
</body>
</html>
I repeat that this was all working completely fine before the mailer stuff went in...but now i'm just baffled. Please help!
Sometimes you are going to want to use more than notice and success, like the Bootstrap alerts info, danger, and warning.
Here is the solution I would recommend:
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %> alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<%= value %>
</div>
<% end %>
That way, when you call flash[:success] = 'foo', your key would be success, and likewise for info, warning, danger, etc. This way you can utilize all of the different Bootstrap alerts.
With this method, you will have to add 2 more CSS classes, that extend the Bootstrap classes, if you want to use the syntax notice: 'hello world', or alert: 'oops' in your redirections, like redirect_to root_url, notice: 'welcome home'.
If you do want to use these, then you can use Sass, like below.
.alert-alert {
#extend .alert-danger;
}
.alert-notice {
#extend .alert-warning;
}
Since my comment earlier on the mailer callback was more of a side note and unrelated to this question, I made a simple gist for ya.
In your flash loop, you are only checking flash[:notice] there. if there is flash[:notice], you applying alert-success. unless it applying alert-danger. So, what i change here. i am applying alert-success for both flash[:success] & flash[:notice]. So,
Do in _flash.html.erb -
<%= content_tag :div, class: "alert alert-#{['success','notice'].include?(key) ? 'success' : 'danger'}" do %>
Try this code in application layout...
<div id="wrapper">
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<% flash.each do |name, msg| %>
<%= content_tag(:div, msg, :id=>"#{name}", :class `enter code here`=>"alert alert- info") %>
<%end%>
</div>
</div>
</div>
</div>
<script type="text/javascript">
window.setTimeout(function()
{
$("#notice").fadeTo(500, 0).slideUp(500, function()
{
$(this).remove();
});
}, 5000);
</script>
<%= yield%>
Oh thanks so much #AmitSuroliya!! This has worked perfectly!! I'm trying to work out what is actually happening here in the code...i don't suppose you could give a short explanation as to why this works could you??...if not thankyou anyway!! I appreciate it so much :)
Justin
PS for people having the same problem and reading this....that solution was copying and pasting this into my application.html.erb file and replacing the content_tag line i had...NOT creating a partial called _flash.html.erb ..just incase anyone was getting confused there :)

Rails 4 - Flash as Key Value Pair Error

I am trying to use Bootstrap styles to Display the Flash messages with color to the users.
Controller
def create
#category = Category.new(category_params)
# Assigning default values
#category.status = 1.to_i
if #category.save
redirect_to admin_categories_path, :flash => { :success => "Category was successfully created." }
else
flash[:error] = "Category could not be save. Please try again."
render :new
end
end
View
<%= render 'admin/partials/flash_message' %>
Partial
<% if flash.present? %>
<%= flash.inspect %>
<% flash.each do |key, value| %>
<div class="<%= flash_class(key) %> fade in widget-inner">
<button type="button" class="close" data-dismiss="alert">×</button>
<%= value %>
</div>
<% end %>
<% end %>
Helper
# Flash Messages
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
Output
I am not able to pass the key to the helper function. I am assuming it sends blank.
This is the HTML that gets outputted
<div class=" fade in widget-inner">
<button data-dismiss="alert" class="close" type="button">×</button>
Category could not be save. Please try again.
</div>
I am not able to figure out why foreach is not able to extract the key and value pair.
on inspect i get the following
#<ActionDispatch::Flash::FlashHash:0x007fc0e74dfa58 #discard=#<Set: {}>, #flashes={"error"=>"Category could not be save. Please try again."}, #now=nil>
in Rails 4, it supports only strings. So i had to change the Helper to the following
# Flash Messages
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
**Edit: According to Deep Suggestions **
By Changing the Flash Partial to
<% if flash.present? %>
<% flash.each do |key, value| %>
<div class="alert alert-<%= key %> fade in widget-inner">
<button type="button" class="close" data-dismiss="alert">×</button>
<%= value %>
</div>
<% end %>
<% end %>
And by Just Extendting the BootStrap Classes as follows we can eliminate the Helper class all together.
alert-notice { #extend .alert-info; }
alert-error { #extend .alert-danger; }

Helper method to change color of alert

I wrote this little helper method:
def alert_color(name)
if name == 'notice'
return 'alert alert-dismissable alert-success'
end
end
In my application layout I wrote:
<% flash.each do |name, msg| %>
<div class=<%= alert_color(name) %>>
<button type="button" class="close" data-dismiss="alert">×</button>
<strong><%= name %></strong><%= msg %>
</div>
<% end %>
My first problem is that it somehow wont work because name isn't passed correctly to the helper_method!
And second problem is that I tried:
alert_color('notice')
and it returned this:
<div class="alert" alert-success="" alert-dismissable="">
I really don't know how to change this behavior!
And, I'm producing flash messages this way:
notice: 'User was successfully updated.'
<div class="<%= alert_color(name) %>">
Besides, you also need to code other cases out of "success" in the helper.
def alert_color(name)
color = name == 'notice' ? 'success' : 'alert'
"alert alert-dismissable alert-#{color}"
end
try interpolation
class="#{alert_color(name)}"

Custom Classes and Formatting on Flash Messages for Twitter Bootstrap defaults

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 %>

DEVISE - successful message when ask for a new password

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
}

Resources