Helper method to change color of alert - ruby-on-rails

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)}"

Related

Variables not showing after post

In rails 4 a page is not showing an instance variable.
I have a form that triggers a post gives a flash message and redirects.
But the values are there and it never shows, any ideas?
slim Form
- unless #flash == nil
= #flash
= form_tag '/contact' do
= email_field_tag('email', nil, id:"email")
input.btn-submit name="submit" type="submit" value="Submit"
Controller
def form_posts_here
if UserMailer.zemail(params[:email]).deliver
flash[:success] = "Thank you!"
end
redirect_to contact_path
end
def new
#flash = flash[:success]
end
Seems like you don't have a way to show the flash messages.
Create a partial _flash.html.erb in your layouts folder and add this block of codes.
<% flash.each do |message_type, message| %>
<div class="alert alert-<%= message_type %> alert-dismissible" role="alert" id="flash">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
<%= simple_format(message) %></div>
<% end %>
You can access this by adding <%= render 'layouts/flash' %> in your application.html.erb.
controller:
def new
flash[:success] = "Message goes here"
end
view:
- if flash[:success].present?
= flash[:success]

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; }

Flash messages appearing twice in rails

My flash messages are appearing twice and my web research tells me this is due to render and redirect displaying the messages. I think I need to use flash.now[] or flash[] somewhere to sort this but I can't work out where it needs to go
guidelines_controller.rb
def update
#guideline = Guideline.find(params[:id])
respond_to do |format|
if #guideline.update_attributes(params[:guideline])
#guideline.update_attribute(:updated_by, current_user.id)
format.html { redirect_to #guideline, notice: 'Guideline was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "show" }
format.json { render json: #guideline.errors, status: :unprocessable_entity }
end
end
end
layouts/application.html.erb
<div class="container">
<% flash.each do |type, message| %>
<div class="alert <%= flash_class type %>">
<button class="close" data-dismiss="alert">x</button>
<%= message %>
</div>
<% end %>
</div>
application_helper.rb
def flash_class(type)
case type
when :alert
"alert-error"
when :notice
"alert-success"
else
""
end
end
guideline_controller.rb
def show
#guideline = Guideline.find(params[:id])
if #guideline.updated_by
#updated = User.find(#guideline.updated_by).profile_name
end
if User.find(#guideline.user_id)
#created = User.find(#guideline.user_id).profile_name
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: #guideline }
end
end
You can do something like this in order to save some lines of code, and display the messages just once:
<%- if flash.any? %>
<%- flash.keys.each do |flash_key| %>
<%- next if flash_key.to_s == 'timedout' %>
<div class="alert-message <%= flash_key %>">
<a class="close" data-dismiss="alert" href="#"> x</a>
<%= flash.discard(flash_key) %>
</div>
<%- end %>
<%- end %>
By using flash.discard, you show the flash message an avoid rendering twice
Just putting this here for anyone else having trouble.
I had flash messages appearing twice because I had something in application.html.erb telling my app to display flash messages, but I had previously generated views with rails generate scaffold posts etc, so that had automatically added the flash messages to all the views.
So the solution was to remove them from the views.
Here's a great tutorial that demonstrates removal for just one model/view
So basically, if you have something like this in your application.html.erb:
<% if notice %>
<p class="alert alert-success"><%= notice %></p>
<% end %>
<% if alert %>
<p class="alert alert-danger"><%= alert %></p>
<% end %>
Then simply remove the equivalent from each of the views. I.e. remove this line from the top of each view
<p id="notice"><%= notice %></p>
I was also having the same issue and also due to another call of <%= render 'shared/alerts' %> later after my check for flash. I liked #rorra's idea of doing a flash_key. But here in the year 2020, it wasn't working as #tessad stated. It would show the message, but not format in bootstrap correctly.
I was able to change their code to work with BootStrap 4. It even dismisses as it is supposed to. The three things that needed to change were all dealing with the class of the div used to display the flash notice.
<div class="alert-message <%= flash_key %>">
alert-message becomes just alert, and the flash_key has to have alert- before it.
<div class="alert alert-<%= flash_key %>">
The last thing is I was sending it to the view from the controller as flash[:notice], which is not a recognized bootstrap alert. When I changed it to flash[:warning] it showed up correctly.
Here is the final code that worked for me. Putting it here in case anyone needs it now 7 years after the initial answer was given.
<div id="container">
<%- if flash.any? %>
<%- flash.keys.each do |flash_key| %>
<%- next if flash_key.to_s == 'timedout' %>
<div class="alert alert-<%= flash_key %>">
<a class="close" data-dismiss="alert" href="#"> x</a>
<%= flash.discard(flash_key) %>
</div>
<%- end %>
<%- end %>
</div>

how to customize devise error messages with classes

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!
For anyone coming across this that does not know how to override the devise error messages with bootstrap.
Create file named:
/app/helpers/devise_helper.rb
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
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 %>
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">×</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!
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

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

Resources