devise gem flash messages - ruby-on-rails

if i am using the devise gem with rails, how do i make the flash messages appear only when theres content inside of it.
does rails have an easy way to do this or do i manually need to do it in jquery?
currently im using twitter bootstrap v2 and it has them built in by default. here is the best jquery i could come up with by the way, im not sure how this could be refactored better (although i definitely know it could be). I had to do it like this because i have an 'x' inside the <p> flash
if($('.alert-success').clone().children().remove().end().text() != "") {
$('.alert-success').fadeIn();
}
if($('.alert-error').clone().children().remove().end().text() != "") {
$('.alert-error').fadeIn();
}
EDIT:
My layout contains:
<p class="alert alert-success"><a class="close" data-dismiss="alert">×</a><%= notice %></p>
<p class="alert alert-error"><a class="close" data-dismiss="alert">×</a><%= alert %></p>

No special methods here, I'd simply control how those tags are output with a surrounding if:
<% if notice %><p class="alert alert-success"><a class="close" data-dismiss="alert">×</a><%= notice %></p><% end %>
<% if alert %><p class="alert alert-error"><a class="close" data-dismiss="alert">×</a><%= alert %></p><% end %>

Related

How to fix duplicate flash alert messages using Devise in Rails app?

I am using Devise to handle user authentication. When a user signs up, I am seeing 2 flash messages displaying the same text.
The blue well I believe is rendered through my application.html.erb:
<!-- Notice -->
<% if notice %>
<div class="alert alert-primary" role="alert">
<center><%= notice %></center>
</div>
<% end %>
However, I am unable to figure out where the 2nd message comes from. Any advice on where I should ook?
you may be using simple_form_for. That gem takes care of the error notice.

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

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

Flash msg optional param

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.

text_area submit issue using Rich Text Editor which outputs HTML

Using tiny_mce from https://github.com/kete/tiny_mce
to be able to change the format of the text, the problem is once its submitted it sends the html to my comments and its not getting translated and just outputs to plain html shown below
<ul> <li><span style="text-decoration: underline;"><strong>hello </strong></span></li> <li><span style="text-decoration: underline;">test</span></li> <li><span style="text-decoration: underline;">est</span></li> <li><span style="text-decoration: underline;">est<br /></span></li> </ul>
How do i get rails to translate the html so it displays boldness etc..
I've tried putting it in HTML tags <html><%= comment.body %></html> which does not work!
Use the raw helper:
<%=raw comment.body %>
You should sanitize the input in your model using a before_validation filter.
I like gem 'sanitize', with it you can self.body = Sanitize.clean( self.body, Sanitize::Config::RESTRICTED )
Then you can safely use <%= raw comment.body %> or <%= comment.body.html_safe %> to display the HTML.

Resources