-
-
Save suryart/7418454 to your computer and use it in GitHub Desktop.
// layout file | |
<body> | |
<div class="container"> | |
<%= flash_messages %> | |
<%= yield %> | |
</div><!-- /container --> | |
</body> |
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 |
thanks, works greate !
+1 for superbilk .. i had to use to_sym for flash_type
Added clearing of flash messages after initial page view, and also had to change the bootstrap_class_for
method to [flash_type.to_sym]
def bootstrap_class_for flash_type
{ success: 'alert-success', error: 'alert-danger', warning: 'alert-warning'}[flash_type.to_sym]
end
def flash_messages(opts = {})
flash.each do |msg_type, message|
concat(content_tag(:div, message, class: "text-center alert #{bootstrap_class_for(msg_type)} fade in") do
concat content_tag(:button, 'x'.html_safe, class: 'close', data: {dismiss: 'alert'})
concat message
end)
flash.clear
end
nil
end
A version that handles array of flashes (eg flash[:notice] = ["something happened", "something else happened"]
), that also lets you define custom flash types (eg flash[:todo]
).
Works on Rails 4.2, Bootstrap 3
Somewhere in application.html.erb
<% flash.each do |type, content| %>
<% if content.respond_to?('each')
content.each do |item| %>
<%= render 'layouts/alert',
type: type,
content: item %>
<% end %>
<% else %>
<%= render 'layouts/alert',
type: type,
content: content %>
<% end %>
<% end %>
_layouts/alert.html.erb
<div class="alert
<%=
case type.to_sym
when :alert, :danger, :error, :validation_errors
'alert-danger'
when :warning, :todo
'alert-warning'
when :notice, :success
'alert-success'
else
'alert-info'
end
%>
alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<%= content %>
</div>
thanks, it rocks
very helpful gist it is.
How to display the flash message at a specific position like flash coming from right side, rather than at the top. Please do help :)
application.html.erb
<% if notice || alert %>
<div class="alert <%= notice ? "alert-info" : "" %><%= alert ? "alert-danger" : "" %> alert-dismissible" role="alert">
<button type="button" class="close" data-dismiss="alert">
<span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<div >
<% if notice %>
<%= notice %>
<% elsif alert %>
<%= alert %>
<% end %>
</div>
</div>
<% end %>
application.js
$(function() {
var flashCallback;
flashCallback = function() {
return $(".alert").fadeOut();
};
$(".alert").bind('click', (function(_this) {
return function(ev) {
return $(".alert").fadeOut();
};
})(this));
return setTimeout(flashCallback, 2000);
});
i ran into an issue with hash access, so my bootstrap_class_for
looks like this:
def bootstrap_class_for flash_type
hash = HashWithIndifferentAccess.new({ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" })
hash[flash_type] || flash_type.to_s
end
i also wanted flash_messages
to be embeddable in a location of my choice (i.e. return the actual HTML for the flashes and not render them at the top of the page), so mine looks like this:
def flash_messages(opts = {})
html_all = ""
flash.each do |msg_type, message|
html = <<-HTML
<div class="alert #{bootstrap_class_for(msg_type)} alert-dismissable"><button type="button" class="close"
data-dismiss="alert" aria-label="Close"><span aria-hidden="true">×</span></button>
#{message}
</div>
HTML
html_all += html
end
html_all.html_safe
end
And did you know, how to test it via Rspec?
Can someone explain to me why I have to use (in HAML):
-flash_messages
instead of
=flash_messages
to get the flash messages to appear where the helper is called rather than automatically being the first element on the page?
@ram619prasad I think this might address your questions also.
Thank s for gist, I used it in Material Design Lite. But there are no "alerts" (yet?) sou basically I borrow CSS from Bootstrap.
@jcmorrow Because the helper concats the flash to the current buffer instead of returning it as a string.
Thanks suryart and melnikaite, all is works good for me. (Rails 4.1)
It's work in rails 4.2.5 and ruby 2.3.0. Thanks!!
I used this way:
def message
html_message = ''
[:success, :info, :error, :notice].each { |tipo|
if flash[tipo]
html_message << "<div class='alert-message alert #{"alert-#{tipo}" if tipo != :alert} alert-block fade in'>"
html_message << '<button type="button" class="close" data-dismiss="alert">×</button>'
html_message << flash[tipo]
html_message << '</div>'
end
}
raw(html_message)
end
Why "success" and "error" aren't show?
How can I use <%= flash_messages %> inside an each loop?
Thank's for gist! It eases my life)))
It took me a while to get this working because its my second day with ruby and rails.
I have rails 4.2.6 with bootstrap-sass 3.3.6 (thanks to Bandon Conway) and it worked with the melnikaite code.
It works perfectly! Thank you so much!
@unknown, according to the following documentation
There are two special accessors for the commonly used flash names alert and notice as well as a general purpose flash bucket.
you have to use the following
redirect_to @resource, alert: 'message'
redirect_to @resource, notice: 'message'
redirect_to @resource, flash: { success: 'message' }
redirect_to @resource, flash: { error: 'message' }
Try extending the bootstrap classes in application.scss
like this:
/* Extending the Bootrstrap classes to cover all possible Flash types */
.alert-alert {
@extend .alert-danger;
}
.alert-notice {
@extend .alert-warning;
}
Apparently in Rails 5 the flash messages each have a string. I just stringified the hash:
def bootstrap_class_for flash_type
{ success: "alert-success", error: "alert-danger", alert: "alert-warning", notice: "alert-info" }.stringify_keys[flash_type.to_s] || 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
This has always worked like a charm for me and I habitually copied and pasted this in my projects, so perhaps I can save someone else a headache. Currently using 'bootstrap', '~> 4.0.0.alpha6'
and fade in
is now fade show
.
To add font-awesome icons in Rails 5, Bootstrap 4 beta 2:
def flash_messages(opts = {})
flash.each do |msg_type, message|
concat(content_tag(:div, message, class: "alert #{bootstrap_class_for(msg_type)} alert-dismissible fade show", role: 'alert') do
concat(content_tag(:button, class: 'close', data: { dismiss: 'alert' }, 'aria-label' => "Close" ) do
concat content_tag(:span, '×'.html_safe, 'aria-hidden' => true)
end)
case
when bootstrap_class_for(msg_type) == "alert-success"
concat content_tag(:span, '<i class="fa fa-check-circle"></i>'.html_safe, 'aria-hidden' => true)
when bootstrap_class_for(msg_type) == ("alert-danger" || "alert-warning")
concat content_tag(:span, '<i class="fa fa-times-circle"></i>'.html_safe, 'aria-hidden' => true)
else
concat content_tag(:span, '<i class="fa fa-info-circle"></i>'.html_safe, 'aria-hidden' => true)
end
concat " " + message
concat " ".html_safe
end)
end
nil
end
Is there a preview of how it works?
@naterexw, this works great. How about having the error message fade out to close after 4 seconds?
A very basic and simple solution for Bootstrap 4:
application_helper.rb
module ApplicationHelper
def bootstrap_class_for(flash_type)
{
success: 'alert-success',
error: 'alert-danger',
alert: 'alert-warning',
notice: 'alert-primary'
}[flash_type.to_sym] || flash_type.to_s
end
end
application.html.erb
<!DOCTYPE html>
<html>
<head>
<!-- . -->
<!-- . -->
</head>
<body>
<div class='container'>
<% flash.each do |type, content| %>
<%= render 'partials/flash', type: type, content: content %>
<% end %>
<%= yield %>
</div>
</body>
</html>
_app/views/partials/flash.html.erb
<div class="alert <%= bootstrap_class_for(type) %> alert-dismissible fade show" role="alert">
<button type="button" class="close" data-dismiss="alert" data-aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<div class="text">
<%= content %>
</div>
</div>
Small typo with https://gist.github.com/suryart/7418454#gistcomment-2584737
correct file name is app/views/partials/_flash.html.erb
(mind the underscore)
thanks