how to customize devise error messages with classes - ruby-on-rails

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

Related

How can i custom devise_error_messages?

I want to show this:
Email can not be blank
Password can not be blank
But i see:
Email can not be blank Password can not be blank
This is Devise_Helper:
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
<div class="alert alert-error alert-danger"> <button type="button"
class="close" data-dismiss="alert">×</button>
#{messages}
</div>
HTML
html.html_safe
end
end
You surely have to change the .yml files settled in:
config/locales/devise.en.yml
Each error has a key and a value .Just change the value you wanted to see and if you don't have the file you can either generate it by yourself or clone it from here.

Validation error message without brackets

On my view, I want to show an error message for each field of my form, below each form field. So Im doing something like this:
<% if #event.errors.full_message(:date, #event.errors[:date]) %>
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Fechar"><span aria-hidden="true">×</span></button>
<%= #event.errors.full_message(:date, #event.errors[:date]) %>
</div>
<% end %>
But the message is coming with brackets and the name of the attribute. I don't want to do an each at the top of the form to show all error messages at the same time. I want to show each error for each input on the form. How do I do that, without brackets and the name of the attribute on the message?
Use brackets [] to retrieve related errors for a field:
In your case:
<% if #event.errors[:date] %>
<div class="alert alert-danger alert-dismissible fade in" role="alert">
<button type="button" class="close" data-dismiss="alert" aria-label="Fechar"><span aria-hidden="true">×</span></button>
<%= #event.errors[:date].join('. ') %>
</div>
<% end %>
#event.errors and is an instance of ActiveModel::Errors, which allows you to use [] to retrieve errors for an attribute. You can also use get in the same way, e.g. #event.errors.get(:some_attribute).
#event.errors[:some_attribute] returns an array of errors on the attribute passed. If you want the full messages, you can use #event.errors.full_messages_for(:some_attribute), which will also return an array.
Your view should check for errors on the attribute like this:
#event.errors.has_key?(:some_attribute)
And you should either iterate over the errors to display them one by one:
#event.errors[:some_attribute].each do |error|
content_tag :span, error, class: 'error'
end
Or join them into a single string or sentence:
#event.errors[:some_attribute].to_sentence
Or show just the first/last of them:
#event.errors[:some_attribute].first

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

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

Resources