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

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 :)

Related

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

Creating Subscription with stripe

I'm trying to create a subscription package using Stripe..
Here what I have so far
My controller method.
def subscription_one
session[:tab] = "$1.99/Month"
#subscription = Subscription.where(user_id:current_user.id)
end
def create
#subscription = Subscription.new(params[:subscription])
if #subscription.save_with_payment
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
subscription_one.html.erb
<% if #subscription.present? %>
CREDIT CARD DETAILS PRESENT
<% else %>
<form action="/membership/apply" method="POST" id="payment-form">
<article>
<label class="amount"> <span>Amount: $5.00</span> </label>
</article>
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500"></script>
<% end %>
After I give all values in fields that appear, when I submit I get an error
ActionController::InvalidAuthenticityToken in MembershipController#create
Any ideas?
Several issues:
--
Form
The form you've included is hard coded
The problem you have is, as stated by Philidor Green, this form won't have the correct authenticity token provided by Rails. As a rule of thumb, Rails provides helpers for most HTML elements, allowing you to create consistent code for your app:
<%= form_tag path do %>
<% end %>
You should use form_tag for this
--
Subscription
Subscription.new(params[:subscription])
Should be:
def subscribed_one
Subscription.new(subscription_params)
end
private
def subscription_params
params.require(:subscription).permit(:params, :attributes)
end
--
Update
To handle this, I'd do this:
#view
<% if #subscription.present? %>
Credit Card Details Present
<% else %>
<%= form_tag membership_apply_path, id: "payment-form" do %>
<%= content_tag :article do %>
<%= label_tag class: "amount" %>
<%= content_tag :span, "Amount: $5.00" %>
<% end %>
<% submit_tag "Susbcribe" %>
<% end %>
<% end %>
#app/views/layouts/application.html.erb
<script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="<%= Rails.configuration.stripe[:publishable_key] %>"
data-description="A month's subscription"
data-amount="500">
</script>
#app/controllers/subscriptions_controller.rb
def subscription_one
session[:tab] = "$1.99/Month"
#subscription = Subscription.where(user_id:current_user.id)
end
def create
#subscription = Subscription.new(params[:subscription])
if #subscription.save_with_payment
redirect_to #subscription, :notice => "Thank you for subscribing!"
else
render :new
end
end
I found a workaround, maybe to simple to be honest, it's the standard stripe checkout, replacing standart Form element by for_path. It seems working :
<%= form_tag stripe_user_standart_charge_checkout_path do %>
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="..."
data-amount="999"
data-name="Grégoire Mulliez"
data-description="Timee"
data-zip-code="true"
data-image="https://stripe.com/img/documentation/checkout/marketplace.png"
data-locale="auto"
data-currency="eur">
</script>
<% end %>
stripe_user_standart_charge_checkout_path is whatever route you want, don't forget to define it as POST (not get) in your routes.rb
Edit : you can retrieve hour transaction token using this method, also I added some html hidden fields to revrieve and the same time my transaction details , it's working like a charme

How to modify bootstrap flash message in rails 4

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.

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

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>

Resources