Styling form error message - bootstrap/rails

前端 未结 8 609
陌清茗
陌清茗 2021-02-01 18:38

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

相关标签:
8条回答
  • 2021-02-01 19:12

    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
    
    0 讨论(0)
  • 2021-02-01 19:13

    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.

    0 讨论(0)
  • 2021-02-01 19:16

    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:

    0 讨论(0)
  • 2021-02-01 19:19

    Take a look at how Michael Hartl does it in railstutorial. screenshot

    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>
          ...
    
    0 讨论(0)
  • 2021-02-01 19:22

    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;
          }
        }
      }
    }
    
    0 讨论(0)
  • 2021-02-01 19:26

    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.

    0 讨论(0)
提交回复
热议问题