Railsのバリデーションエラー時に、field_with_errorsの自動挿入によってフォームのレイアウト崩れが起こる問題のトラブルシューティングです。
開発環境
- Ruby 3.1.2
- Ruby on Rails 7.0.3
- M1 Macbook Air 2020
- mac OS Monterey (ver. 12.4)
- ターミナル bash (Rosetta 2 使用)
Railsのバリデーションエラーでフォームのレイアウト崩れが起こる問題
フォームをRailsのフォームヘルパーform_withで生成すると、あるフィールドでバリデーションエラーが発生すると、そのエントリの周りにfield_with_errorsクラスを持った<div>が自動的に生成されます。
<div class="field_with_errors">
<input id="article_title" name="article[title]" size="30" type="text" value="">
</div>本来なら便利でありがたい機能なのですが、レイアウトの組み方次第では追加された<div>によってレイアウト崩れを引き起こしてしまいます。
今回はその一例を見てみましょう。
以下のフォームはBootstrap5で組んだものです。

あえてバリデーションエラーを引き起こしてみると、以下のようにレイアウトが崩れてしまいます。

検証で要素を見てみると、<label>と<input>の周りにfield_with_errorsクラスのdivが挿入されていることがわかります。

この<div>によって、周辺の密接に関連している要素が崩されてしまいます。
どういうことかというと、今回用意したフォームのレイアウトは、Bootstrapのinput-groupクラスによってフィールド内にアイコンを埋め込むような形にしています。

そのため、以下のように<div class="input-group">内では<span>と<input>を横並びにする必要があります。
<div class="input-group">
<span class="input-group-text" id="basic-addon1">
<i class="bi bi-person-circle"></i>
</span>
<input placeholder="ユーザー名を入力してください" class="form-control" type="text" name="user[name]" id="user_name">
</div>しかし、そこにいきなりfield_with_errorsクラスの<div>が割り込んでくると、<div class="input-group">から見た<span>と<input>の関係が崩れてしまい予期しないレイアウトになってしまうのです。
<div class="input-group">
<span class="input-group-text" id="basic-addon1">
<i class="bi bi-person-circle"></i>
</span>
<div class="field_with_errors">
<input placeholder="ユーザー名を入力してください" class="form-control" type="text" name="user[name]" id="user_name">
</div>
</div>これを防ぐ方法について検証していきます。
field_with_errors によるレイアウト崩れを防ぐ方法
Railsのfield_with_errorsによるレイアウト崩れを防ぐ方法は2つあります。
1つは、field_with_errorsクラスにdisplay: contents;を追記します。
.field_with_errors {
display: contents;
}しかし、今回のようにフィールド内にアイコンを埋め込んでいる場合は、上記の方法ではうまくいきません。
そこで、2つ目の方法としてfield_with_errorsを自動挿入させないように設定します。
config/application.rbに以下の1行を記述するだけでOKです。
・・・
module HomestayMatching
class Application < Rails::Application
・・・
# 追記 #
config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag }
end
end追記したら、Railsサーバーを再起動して更新します。
すると、field_with_errorsが自動挿入されなくなり、レイアウト崩れの問題も解決できました。

以上です。


コメント