メール欄:
<label for="job_client_email">Email: </label>
<input type="email" name="job[client_email]" id="job_client_email">
次のようになります。
ただし、電子メールの検証に失敗すると、次のようになります。
<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>
次のようになります。
この外観の変更を回避するにはどうすればよいですか?
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サーバーを再起動します。
div
要素はブロック要素であるため、視覚的な違いが生じています。このスタイルをCSSファイルに追加して、インライン要素のように動作させます。
.field_with_errors { display: inline; }
現在、このソリューションを使用して、初期化子に配置します。
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
これにより、追加の要素を作成せずに、適切なタグにクラス名を追加するだけで済みます。
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 }
私はRails 5および Materialize-Sass で作業しており、Rails下の画像のようにフィールド検証が行われましたが、これは検証が失敗した入力フィールドに余分なdiv
が追加されたためです。
@Phobetronの回答を使用し、Hugo Demiglioの回答も変更します。これらのコードブロックにいくつかの調整を加えたところ、次のような場合にうまく機能します。
input
とlabel
の両方が独自のclass
属性をどこかに持っている場合<input type="my-field" class="control">
<label class="active" for="...">My field</label>
input
または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
属性の既存のクラスに追加され、ラベルに存在しない場合は作成されますまたはinputタグ。
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
私と同じ状態の人に役立つといいのですが。
@phobetronの回答に加えて、<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
一部のオブジェクトでこの恐ろしいことを無効にするオプションを作成しました
# 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
何らかの理由でまだ作業している場合、Rails 2(私と同じ))SO post here 。
初期化子を配置するスクリプトを提供します。
心に留めておくべきことの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;
}
それがスタイリングのためだけである場合(div
を気にしない)、これをcssに追加するだけです:
div.field_with_errors {
display: inline;
}
div
はspan
のように機能し、設計に干渉しません(div
はブロック要素であるため– display: block;
–デフォルトでは、閉じると新しい行が作成されます。 span
はinline
であるため、そうではありません)。
これは、@ Phobetronの答えの上に構築された私のソリューションです。このコードをapplication.rb
に配置すると、対応する<p>
呼び出しによって生成された<span>
およびform.error :p
タグがfields_with_errors
cssタグを受け取ります。残りはerror
CSSクラスを受け取ります。
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
}
この方法は、フォーム全体で応答をスタイルするために、以前のすべての中で最も柔軟で目立たないものであることがわかりました。
スタイリングの問題のみの場合は、「field_with_errors」を上書きできます。しかし、それはアプリケーションの他のフォームに影響を与える可能性があるため、そのフィールドのみで「field_with_errors」クラスを上書きする方が適切です。
'parent_class'がフォームのエラーフィールドの親クラス(フォームのクラスまたはエラーフィールドの親要素のクラスのいずれか)の1つであることを考慮すると、
.parent_class .field_with_errors {
display: inline;
}
問題を修正するだけでなく、アプリケーション内の他のフォームも邪魔しません。
OR
アプリケーション全体で「field_with_errors」のスタイルをオーバーライドする必要がある場合は、@ dontanggが言ったように、
.field_with_errors { display: inline; }
修正を行います。それが役に立てば幸い :)
特定の要素のエラーをオフにしたいだけなら、例えばチェックボックス、これを行うことができます:
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