自定义 field_with_errors

问题描述 投票:0回答:16

有没有办法告诉 Rails 不要在标签和实际字段周围创建

div.field_with_errors
,而是在它们周围创建
div.error

例如我视图中的代码片段(用 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 样式的元素,没有 formtastic 的 css 和 html 类,但是有引导程序的。在使用 formtastic 的情况下,我可以制作带有错误字段的东西吗?

ruby-on-rails ruby-on-rails-3 customization formtastic twitter-bootstrap
16个回答
17
投票

@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
}

9
投票

创建

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

7
投票

如果有人使用LESS:

在 bootstrap_and_overrides.css.less 你可以添加:

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

.field_with_errors {
  .control-group.error();
}

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


5
投票

这是在使用 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);
}

4
投票

这是我对 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;
}

3
投票

如果您将 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 选择器中。


2
投票

Bootstrap 5,Rails 7。 正如其他用户所述,您可以通过在初始化程序中设置 ActionView::Base.field_error_proc 来覆盖此行为。据我了解,你想要这样的东西:

ActionView::Base.field_error_proc = proc { |html| tag.div html, class: "errors" }

我想重写它以完全不包装 html,而是将“is-invalid”注入原始 HTML 的类中。我更喜欢使用 Nokogiri 将其解析为 DomFragment 并以这种方式更新类,而不是使用正则表达式。

ActionView::Base.field_error_proc = proc do |html| 
  frag = Nokogiri::HTML5::DocumentFragment.parse(html)
  klass = frag.children[0].attributes['class']
  frag.children[0].attributes['class'].value = [klass, 'is-invalid'].join(' ')
  frag.to_html.html_safe
end

1
投票

以下是我想出的。

我将其添加到我的 css

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

我把这个添加到

<head>

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

1
投票

我的积分不够评论,所以我会在这里回答:

添加@iosctr 的答案——CSS 仅在我添加到我的

bootstrap_and_overrides.css.scss
文件后才开始工作:

@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;
} 

1
投票

使用 bootstrap 3.0,类是

has-error
。 @oded 的解决方案应该是:

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

0
投票

其实比你想象的更让人恼火

我最终创建了自己的标签助手(我也需要用于其他目的),尽管我一开始只是覆盖

ActionView::Base.field_error_proc
。 (这本身就是一个故事,因为它传递一个字符串,实际上不是你可以可靠地摆弄的东西:(

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


0
投票

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


0
投票

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

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

它基本上采用默认的 Rails 行为并将其转换为 Bootstrap 行为。将错误类添加到它所属的

control-group
中。 没有
css
也没有覆盖默认值
field_error_proc
.


0
投票

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;
    }
}

0
投票

是的,你可以破解包装器 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

0
投票

jpgeek 的回答在 most 情况下对我有用。但是,如果

input
标签不具有 CSS 类属性 already,它将无法工作但会破坏应用程序(至少在我的 Rails 7 应用程序中)。所以这是对我有用的代码:

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  if html_tag =~ /<(input|textarea|select)/
    html_field = Nokogiri::HTML::DocumentFragment.parse(html_tag)
    html_field.children.add_class("invalid")
    html_field.to_html.html_safe
  else
    html_tag
  end
end
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.