134

メールフィールド:

<label for="job_client_email">Email: </label> 
<input type="email" name="job[client_email]" id="job_client_email">

このように見えます:

without_error

ただし、電子メールの検証が失敗した場合は、次のようになります。

<div class="field_with_errors">
  <label for="job_client_email">Email: </label>
</div> 
<div class="field_with_errors">
  <input type="email" value="wrong email" name="job[client_email]" id="job_client_email">
</div>

これは次のようになります:

with_error

この外観の変化をどのように回避できますか?

4

15 に答える 15

238

をオーバーライドする必要がありますActionView::Base.field_error_proc。現在、次のように定義されていますActionView::Base

 @@field_error_proc = Proc.new{ |html_tag, instance| 
   "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
 }

これをアプリケーションのクラスに入れることでオーバーライドできますconfig/application.rb

config.action_view.field_error_proc = Proc.new { |html_tag, instance| 
  html_tag
}

この変更を有効にするには、Railsサーバーを再起動します。

于 2011-03-11T01:45:42.657 に答える
102

div要素がブロック要素であるため、表示されている視覚的な違いが発生しています。このスタイルをCSSファイルに追加して、インライン要素のように動作させます。

.field_with_errors { display: inline; }
于 2011-03-11T01:38:35.200 に答える
72

私は現在、イニシャライザーに配置されたこのソリューションを使用しています。

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index 'class="'

  if class_attr_index
    html_tag.insert class_attr_index+7, 'error '
  else
    html_tag.insert html_tag.index('>'), ' class="error"'
  end
end

これにより、追加の要素を作成せずに、適切なタグにクラス名を追加するだけで済みます。

于 2011-12-05T02:29:20.657 に答える
21

余分なコードはによって追加されていActionView::Base.field_error_procます。フォームのスタイル設定に使用していない場合はfield_with_errors、次のようにオーバーライドできますapplication.rb

config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag.html_safe }

または、UIに適したものに変更することもできます。

config.action_view.field_error_proc = Proc.new { |html_tag, instance| "<span class='field_with_errors'>#{html_tag}</span>".html_safe }
于 2011-03-11T01:46:24.760 に答える
5

Rails 5とMaterialize-Sassを使用していますが、Railsのデフォルトの動作で問題が発生し、失敗したフィールドの検証を下の画像のように処理しています。これはdiv、検証が失敗した入力フィールドに余分なものが追加されたためです。

ここに画像の説明を入力してください

@Phobetronの回答を使用して、HugoDemiglioの回答も変更します。これらのコードブロックにいくつかの調整を加えたところ、次の場合にうまく機能するようになりました。

  • 両方ともinput、どこか labelに独自の属性がある場合class
    • <input type="my-field" class="control">
    • <label class="active" for="...">My field</label>
  • inputorタグに属性 labelがない場合class
    • <input type="my-field">
    • <label for="...">My field</label>
  • labelタグの中に別のタグがあり、class attribute
    • <label for="..."><i class="icon-name"></i>My field</label>

これらすべての場合において、クラスは、存在する場合は属性error内の既存のクラスに追加され、ラベルまたは入力タグclassに存在しない場合は作成されます。

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
    class_attr_index = html_tag.index('class="')
    first_tag_end_index = html_tag.index('>')

    # Just to inspect variables in the console
    puts ' ' * 50
    pp(html_tag)
    pp(class_attr_index)
    pp(first_tag_end_index)

    if class_attr_index.nil? || class_attr_index > first_tag_end_index
        html_tag.insert(first_tag_end_index, ' class="error"')
    else
        html_tag.insert(class_attr_index + 7, 'error ')
    end

    # Just to see resulting tag in the console
    pp(html_tag)
end

私のような同じ条件の人に役立つことを願っています。

于 2017-01-30T05:54:38.827 に答える
4

@phobetron answerに加えて、。のようなクラス属性を持つ他のタグがある場合は機能しません<label for="..."><i class="icon my-icon"></i>My field</label>

私は彼の解決策にいくつかの変更を加えました:

# config/initializers/field_with_error.rb

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  class_attr_index = html_tag.index('class="')
  first_tag_end_index = html_tag.index('>')

  if class_attr_index.nil? || first_tag_end_index > class_attr_index
    html_tag.insert(class_attr_index + 7, 'error ')
  else
    html_tag.insert(first_tag_end_index, ' class="error"')
  end
end
于 2016-03-28T20:02:11.380 に答える
2

何らかの理由でまだRails2で作業している場合は(私のように)、ここでSOの投稿を確認してください。

初期化子を挿入するためのスクリプトを提供します。

于 2012-05-30T20:16:33.187 に答える
2

覚えておくべきことの1つは(今日これを通して作業していることを発見したように)、ラベルまたは入力フィールドのいずれかをフロートすると(すべての入力フィールドを正しくフローティングしている)、ActionViewをオーバーライドしてもcssが壊れることです:: Base.field_error_proc。

別の方法は、次のようにCSSフォーマットのレベルを深くすることです。

.field_with_errors label {
  padding: 2px;
  background-color: red;
}

.field_with_errors input[type="text"] {
  padding: 3px 2px;
  border: 2px solid red;
}
于 2012-06-06T19:53:23.333 に答える
2

一部のオブジェクトでこのひどいことを無効にするオプションを作成しました

# config/initializers/field_error_proc.rb

module ActiveModel::Conversion
  attr_accessor :skip_field_error_wrapper
end

ActionView::Base.field_error_proc = Proc.new {|html_tag, instance|
  if instance.object && instance.object.skip_field_error_wrapper
    html_tag.html_safe
  else
    "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
  end
}

したがって、次のように使用できます。

@user.skip_field_error_wrapper = true
form_for(@user) do |f|
  ...
end
于 2015-01-15T06:29:33.217 に答える
1

これは、@Phobetronの回答に基づいて構築された私のソリューションです。このコードをに配置すると、対応する呼び出しによって生成されたapplication.rbyourタグ<p>とタグがcssタグを受け取ります。残りはCSSクラスを受け取ります。<span>form.error :pfields_with_errorserror

config.action_view.field_error_proc = Proc.new { |html_tag, instance|
  class_attr_index = html_tag.index 'class="'

  if class_attr_index
    # target only p's and span's with class error already there
    error_class = if html_tag =~ /^<(p|span).*error/
      'field_with_errors '
    else
      'error '
    end

    html_tag.insert class_attr_index + 7, error_class
  else
    html_tag.insert html_tag.index('>'), ' class="error"'
  end
}

この方法は、フォーム全体で応答のスタイルを設定するために、これまでのすべての中で最も柔軟で目立たないものであることがわかりました。

于 2013-11-11T13:51:18.870 に答える
1

それがスタイリングの目的だけである場合(あなたは気にしないdivでください)、あなたはこれをあなたのcssに追加することができます:

div.field_with_errors {
 display: inline;
}

はのdivように機能spanし、デザインに干渉しません(divブロック要素であるためdisplay: block;、デフォルトでは、閉じた後に新しい行が表示されます。spaninline、そうではありません)。

于 2014-03-28T14:29:22.040 に答える
1

チェックボックスなど、特定の要素のエラーをオフにするだけの場合は、次のように実行できます。

ActionView::Base.field_error_proc = Proc.new do |html_tag, instance|
  doc = Nokogiri::HTML::Document.parse(html_tag)
  if doc.xpath("//*[@type='checkbox']").any?
    html_tag
  else
    "<div class=\"field_with_errors\">#{html_tag}</div>".html_safe
  end
end
于 2019-08-21T16:53:58.167 に答える
0

スタイリングの問題だけの場合は、「field_with_errors」を上書きできます。ただし、これはアプリケーションの他のフォームに影響を与える可能性があるため、「field_with_errors」クラスをそのフォームのみで上書きすることをお勧めします。

'parent_class'がフォームのエラーフィールドの親クラスの1つ(フォームのクラスまたはエラーフィールドの親要素のいずれかのクラス)であると考えると、

  .parent_class .field_with_errors {
    display: inline;
  }

それは問題を修正するだけでなく、私たちのアプリケーションの他のフォームを邪魔することもありません。

また

アプリケーション全体で「field_with_errors」のスタイルをオーバーライドする必要がある場合は、@dontanggが言ったように

.field_with_errors { display: inline; } 

修正を行います。それが役に立てば幸い :)

于 2014-04-21T12:00:30.043 に答える
0

field_error_procアプリケーション全体を変更したくない場合は、jQueryのアンラップにより、特定の問題領域に対してより的を絞ったソリューションを提供できます。

$('FORM .field_with_errors > INPUT[type="checkbox"]').unwrap();
于 2020-06-11T20:49:03.377 に答える
0

特定のフォーム要素で追加のdivがまったく<div class="field_with_errors">必要ない場合は、簡単に完全に無効にすることができます。たとえば、が必要ない場合は、カスタムFormBuilderを使用します。<label>

例えば:

class MyFormBuilder < ActionView::Helpers::FormBuilder
  # Strip the containing div for labels associated with invalid fields:
  def label(method, text = nil, options = {}, &block)
    super(method, text, options, &block).gsub(%r{<div.*?>|<\/div>}, '').html_safe
  end
end

次に、ビューの/に追加するか、コントローラー(またはグローバルな動作が必要な場合はベースコントローラー)に追加します。, builder: MyFormBuilderform_withform_fordefault_form_builder MyFormBuilder

入力やその他のフォーム要素についても同様に行うことができます。

この回答はJackCaseyの功績によるものです。

于 2020-08-06T02:14:19.123 に答える