【问题标题】:Customizing field_with_errors自定义 field_with_errors
【发布时间】:2011-09-17 12:20:18
【问题描述】:

有没有办法告诉 Rails 不要在标签和实际字段周围创建div.field_with_errors,而是在它们周围创建div.error

例如从我的角度来看 sn-p 表单(用 HAML 编写)

= form_for @user do |f|
  %div.clearfix
    = f.label :name
    %div.input
      = f.text_field :name

如果出现错误,我希望根 div 为 div.clearfix.error,并避免使用 field_with_errors。我可以这样做吗?

作为另一种选择,我可以使用 formtastic 来创建 Bootstrap-styled 元素,没有 formtastic 的 css 和 html 类,但使用 bootstrap 类。在使用formtastic的情况下,我可以制作带有错误字段的东西吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 customization formtastic twitter-bootstrap


    【解决方案1】:

    @flowdelic 的答案似乎是最简单的解决方法。但是,名称不正确。 这可能是由于 Rails/Bootstrap 版本,但这对我有用。

    /* Rails scaffold style compatibility */
    #error_explanation {
      @extend .alert;
      @extend .alert-error;
      @extend .alert-block; /* optional */
    }
    
    .field_with_errors {
      @extend .control-group.error
    }
    

    【讨论】:

    • 新的@extend .alert-danger;
    【解决方案2】:

    使用:创建config/initializers/field_with_errors.rb

    ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
      "<div class=\"error\">#{html_tag}</div>".html_safe
    end
    

    这会将.field-with-errors 替换为.error

    但是,我发现“Rails-way”的最大问题是它使用新的div 包装元素,而不是简单地将类添加到元素本身。我更喜欢这个:

    ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
      parts = html_tag.split('>', 2)
      parts[0] += ' class="field_with_errors">'
      (parts[0] + parts[1]).html_safe
    end
    

    【讨论】:

    • 这应该是公认的答案。可惜 html_tag 是一个 ActiveSupport::SafeBuffer,基本上是一个字符串变体,这样封装起来很容易,但修改起来非常困难!
    • 这是要走的路。不过,为了维护当前的课程,我改用它:html_tag.gsub(/class="(.*?)"/, 'class="\1 is-invalid"')
    【解决方案3】:

    如果有人使用 LESS:

    您可以在 bootstrap_and_overrides.css.less 中添加:

    #error_explanation {
      .alert();
      .alert-error();
      .alert-block();
    }
    
    .field_with_errors {
      .control-group.error();
    }
    

    这是所示 sass 示例的 LESS 版本。

    【讨论】:

    • 在较新的 Bootstrap 版本中,这将是:.has-error() 而不是 .control-group.error()
    【解决方案4】:

    当使用 https://github.com/anjlab/bootstrap-rails gem 时,这适用于 Bootstrap 3。

    .field_with_errors {
      @include form-control-validation($state-danger-text, $state-danger-text, $state-danger-bg);
    }
    

    【讨论】:

      【解决方案5】:

      这是我对 bootstrap 3.0.3 和 rails 4.0.2 所做的:

      /* Rails scaffold style compatibility */
      #error_explanation {
        @extend .alert;
        @extend .alert-danger;
        width: inherit;
      }
      
      .field_with_errors {
        @extend .has-error;
        display: inherit;
        padding: inherit;
        background-color: inherit;
      }
      

      【讨论】:

        【解决方案6】:

        如果您将 SASS 与 Twitter Bootstrap 一起使用,则可以使用 @extend 指令将 Twitter Bootstrap 样式应用于 Rails 生成的 CSS 类。 (搜索 GitHub,有几个 Bootstrap/SASS 端口可用。)

        例如:

        @import "bootstrap";
        
        /* Rails scaffold style compatibility */
        .errorExplanation {
          @extend .alert-message;
          @extend .block-message;
          @extend .error;
        }
        
        .fieldWithErrors {
          // pulled from div.clearfix.error
          @include formFieldState(#b94a48, #ee5f5b, lighten(#ee5f5b, 30%));
        }
        

        请注意,“错误”的 Twitter Bootstrap 样式附加到 div.clearfix 选择器,这使我们无法简单地执行此操作:

        .fieldWithErrors {
          @extend .error;
        }
        

        因此,我将 Bootstrap 中 div.clearfix.error 定义中的代码复制/粘贴到我的 .fieldWithErrors 选择器中。

        【讨论】:

          【解决方案7】:

          以下是我想出的。

          我将此添加到我的 CSS 中

          .field_with_errors {
              display:inline;
              margin:0px;
              padding:0px;
          }
          

          我将此添加到&lt;head&gt;

          $(function(){
              $('.field_with_errors').addClass('control-group error');
          });
          

          【讨论】:

            【解决方案8】:

            我没有足够的评论,所以我会在这里回答:

            添加到@iosctr 的答案——只有在我添加到我的bootstrap_and_overrides.css.scss 文件后,css 才开始工作:

            @import "bootstrap";
            body { padding-top: 40px; }
            @import "bootstrap-responsive";
            
            #error_explanation {
              @extend .alert;
              @extend .alert-error;
              @extend .alert-block; 
            }
            
            .field_with_errors {
              @extend .control-group.error;
            } 
            

            【讨论】:

              【解决方案9】:

              使用 bootstrap 3.0,类是 has-error。 @oded 的解决方案应该是:

              $('.field_with_errors').parent().addClass('has-error');
              

              【讨论】:

              • 如果你使用 SASS:.field_with_errors { @extend .has-error; }
              【解决方案10】:

              这实际上比你想象的更烦人。

              我最终创建了自己的标签助手(我也需要它用于其他目的),尽管我刚开始只是覆盖ActionView::Base.field_error_proc。 (这本身就是一个故事,因为它以字符串形式传递,实际上并不是您可以可靠地摆弄的东西:(

              但是从那开始,看看它是否对你足够,否则准备一些挖掘和调整。

              【讨论】:

                【解决方案11】:

                您可以使用 Formtastic Bootstrap gem 通过 Formtastic 创建 Twitter Bootstrap 友好的标记。

                【讨论】:

                  【解决方案12】:

                  对于所有这些混乱,有一个非常简单的解决方案。它是基于 javascript 的,但它解决了我的问题 - 只需添加这个(当你使用水平形式时):

                  $(document).ready(function() {
                      $('.field_with_errors').parent().addClass('error');
                  });
                  

                  它基本上采用默认的 Rails 行为并将其转换为 Bootstrap 行为。将错误类添加到它所属的control-group。 没有css,也没有覆盖默认的field_error_proc

                  【讨论】:

                    【解决方案13】:

                    Bootstrap 3 和 Rails 4 -- 我必须执行以下操作:

                    .alert-error{
                        color: #f00;
                        @extend .alert;
                        @extend .alert-danger;
                    }
                    
                    #error_explanation
                    {   ul
                        {
                            list-style: none;
                            margin: 0 0 18px 0;
                            color: red
                        }
                    }
                    
                    .field_with_errors
                    {
                        input {
                        border: 2px solid red;
                        }
                    }
                    

                    【讨论】:

                      【解决方案14】:

                      是的,您可以破解包装器 div。借用this tipoff,我对其进行了修改,将包装器转换为标签上的invalid 类,并自行形成输入...

                      把它放在你的配置中的某个地方(例如environments.rb

                      ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
                        (html_tag.gsub /class="(.*?)"/, 'class="\1 invalid"').html_safe
                      end
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2013-11-23
                        • 2012-11-10
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2017-10-17
                        相关资源
                        最近更新 更多