The error messages for my rails form look terrible with bootstrap. Does anyone know a solution for better (nice looking) error messages? I use Rails and Bootstrap.
My fo
I've create a custom initializer to have each field having its own errors below it
# app/config/initializers/bootstrap_form_errors_customizer.rb
ActionView::Base.field_error_proc = proc do |html_tag, instance|
is_label_tag = html_tag =~ /^<label/
class_attr_index = html_tag.index 'class="'
def format_error_message_to_html_list(error_msg)
html_list_errors = "<ul></ul>"
if error_msg.is_a?(Array)
error_msg.each do |msg|
html_list_errors.insert(-6,"<li>#{msg}</li>")
end
else
html_list_errors.insert(-6,"<li>#{msg}</li>")
end
html_list_errors
end
invalid_div =
"<div class='invalid-feedback'>#{format_error_message_to_html_list(instance.error_message)}</div>"
if class_attr_index && !is_label_tag
html_tag.insert(class_attr_index + 7, 'is-invalid ')
html_tag + invalid_div.html_safe
elsif !class_attr_index && !is_label_tag
html_tag.insert(html_tag.index('>'), ' class="is-invalid"')
html_tag + invalid_div.html_safe
else
html_tag.html_safe
end
end
A little late I realize, but I just ran into this today with Rails 4 and Bootstrap 3, I ended up making a view helper to display errors using a panel:
Rails 4 / Bootstrap 3
def errors_for(object)
if object.errors.any?
content_tag(:div, class: "panel panel-danger") do
concat(content_tag(:div, class: "panel-heading") do
concat(content_tag(:h4, class: "panel-title") do
concat "#{pluralize(object.errors.count, "error")} prohibited this #{object.class.name.downcase} from being saved:"
end)
end)
concat(content_tag(:div, class: "panel-body") do
concat(content_tag(:ul) do
object.errors.full_messages.each do |msg|
concat content_tag(:li, msg)
end
end)
end)
end
end
end
Rails 4 / Bootstrap 4 Beta
def errors_for(object)
if object.errors.any?
content_tag(:div, class: "card border-danger") do
concat(content_tag(:div, class: "card-header bg-danger text-white") do
concat "#{pluralize(object.errors.count, "error")} prohibited this #{object.class.name.downcase} from being saved:"
end)
concat(content_tag(:div, class: "card-body") do
concat(content_tag(:ul, class: 'mb-0') do
object.errors.full_messages.each do |msg|
concat content_tag(:li, msg)
end
end)
end)
end
end
end
Rails 4 / Bootstrap 4 Beta List Group Variation
def errors_for(object)
if object.errors.any?
content_tag(:div, class: "card border-danger") do
concat(content_tag(:div, class: "card-header bg-danger text-white") do
concat "#{pluralize(object.errors.count, "error")} prohibited this #{object.class.name.downcase} from being saved:"
end)
concat(content_tag(:ul, class: 'mb-0 list-group list-group-flush') do
object.errors.full_messages.each do |msg|
concat content_tag(:li, msg, class: 'list-group-item')
end
end)
end
end
end
I dropped it in application_helper and call it in my form views
<%= errors_for(@user) %>
Maybe someone will stumble upon this and find it useful.
I have implemented Rabbott's view helper in Rails 5 and Bootstrap 4:
def errors_for(object)
if object.errors.any?
content_tag(:div, class: 'card text-white bg-danger mb-3') do
concat(content_tag(:div, class: 'card-header') do
concat(content_tag(:h4) do
concat "#{pluralize(object.errors.count, 'error')} prohibited this #{object.class.name.downcase} from being saved:"
end)
end)
concat(content_tag(:div, class: 'card-body') do
concat(content_tag(:ul) do
object.errors.full_messages.each do |msg|
concat content_tag(:li, msg)
end
end)
end)
end
end
end
And it looks like this:
Take a look at how Michael Hartl does it in railstutorial.
And thats the used css:
#error_explanation {
color: #f00;
ul {
list-style: none;
margin: 0 0 18px 0;
}
}
.field_with_errors {
@extend .control-group;
@extend .error;
}
He describes everything here.
If you also want the little star at the beginning of every line you have to include it in your form:
<div id="error_explanation">
<h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li> * <%= msg %></li> <--- insert here
<% end %>
</ul>
</div>
...
Another variation with SCSS only
#error_explanation{
background: #f23551;
color: #fff;
border-radius: 4px;
margin-bottom: 20px;
h2{
padding: 20px;
margin: 0;
font-size: 20px;
}
ul{
background: #fff;
color: #e5324a;
border: 1px solid #F23551;
margin: 0;
list-style: none;
padding: 14px 0;
li{
padding: 4px 20px;
&:before {
content: '×';
font-weight: bold;
font-size: 20px;
margin-right: 10px;
}
}
}
}
Just in case someone stumbles here and is using Bootstrap 4 alpha
with rails 5
and bootstrap_form_for gem
.
I use:
<div class="form-group">
<%= f.alert_message "Please fix the errors below." %>
</div>
which looks really nice.