LoginSignup
0
0

More than 1 year has passed since last update.

Ratyを使ったレビュー機能 バリデーションエラーの表示方法

Posted at

実装内容

Bootstrap4では、サーバーサイドでチェックした入力エラーのメッセージを表示するための「invalid-feedback」クラスが用意されており、項目ごとに分かりやすく表示されるようになっています。

しかし、入力欄に<input>タグを使用していない場合、このエラーメッセージは表示されません、、(自分の場合、Ratyを使ったレビュー機能で起こりました、、)

この問題に遭遇し参考記事を探してみたのですが、該当する記事を見つけることができなかったこともあり、備忘録も兼ねて紹介しています。

処理全体の流れ

  1. 三項演算子を使用して適切なクラスの付与
  2. styleの修正
  3. エラーメッセージ表示用のdivタグ作成

完成形はこちら

Before

Image from Gyazo

After

Image from Gyazo

入力後

Image from Gyazo

環境

macOS Big Sur 11.2.3
ruby: 2.7.2
rails: 6.1.3
jQuery
テンプレートエンジン: slim
レイアウト: bootstrap4

前提

  • gem bootstrap4 と Ratyの導入は省いております

修正前のviewファイル

まず、修正前のコードを御覧ください。

app/views/travel_records/new.html.slim
= simple_form_for @travel_record do |f|
 = render 'layouts/error_messages', model: f.object
・
・
・
  #star
    = f.label :'オススメ度【必須】', required: false
    .d-flex
      = f.hidden_field :review, id: :review_star
  = render 'shared/star' 

レビュー機能のため、 カラム名をreviewとしています。
Ratyの動作に必要なjsコードはパーシャル化し、= render 'shared/star'で呼び出しています。

また、バリデーションはvalidates :review, presence: trueとし、入力がない場合にエラーを表示させるようにしています。

修正後のviewファイル

こちらが完成形のコードになります。
※スタイル適用時にレビュー星を枠で囲って表示するため、コードの記述順を変更しています。

app/views/travel_records/new.html.slim
= simple_form_for @travel_record do |f|
 = render 'layouts/error_messages', model: f.object
・
・
・
  = f.label :'オススメ度【必須】', required: false
  - is_error = f.object.errors[:review].present? 
  #star class=(is_error ? 'form-control is-invalid' : 'form-control is-valid' if @travel_record.review? || is_error)
    .d-flex
      = f.hidden_field :review, id: :review_star
      = render 'shared/star', show_raty: 'new'
  div class=("invalid-feedback #{f.object.errors[:review].present? ? 'd-block' : 'd-none'}")
    | オススメ度を入力してください

エラーメッセージのファイル

app/views/layouts/_error_messages.html.slim
- if model.errors.any?
 - model.errors.full_messages.each do | error_message |
  .alert.alert-danger.alert-dismissible.mb-2 role="alert"
    button type="button" class="close" data-dismiss="alert"
      span aria-hidden="true" &times;
      span.sr-only close
    = error_message

それでは順を追って説明いたします。

赤枠の表示

まず初めに、エラー時に表示される赤枠の実装から行なっていきます。

app/views/travel_records/new.html.slim
- is_error = f.object.errors[:review].present? # コードが重複しているため、変数に格納
#star class=(is_error ? 'form-control is-invalid' : 'form-control is-valid' if @travel_record.review? || is_error)

赤枠を表示させるにはbootstrapクラスform-controlis-invalidが必要になり、入力があった場合、緑枠を表示させるため、form-controlis-validが必要になります。

また、入力の有無で表示を切り替えるため、三項演算子を使用して条件によって適切なクラスを付与するようにしています。

まず、三項演算子でクラスを付与する前にif @travel_record.review? || is_errorで条件分岐しています。
※ この記述をしないと、未入力の場合でも緑枠が表示されてしまいます。

上記コードでは、f.object.errors[:review].present?でエラーの有無をチェックしています。エラーの場合はform-controlis-invalidを付与して赤枠を表示させ、入力があった場合はform-controlis-validを付与して緑枠を表示させています。

styleの修正

レビュー星を枠で囲って表示するため、styleの修正をしています。

app/assets/stylesheets/aplication.scss
// エラーメッセージの設定
.form-control {
  height: auto;
}

form-controlheightが悪さをしており、値をautoに変更した所、うまく表示することができました。

エラーメッセージの表示

次に、エラーメッセージ表示の実装を行なっていきます。

div class=("invalid-feedback #{is_error ? 'd-block' : 'd-none'}")
 | オススメ度を入力してください

赤文字のエラー文を表示するにはinvalid-feedbackクラスをもつ<div>タグが必要になります。
こちらも三項演算子を使用し、エラーの場合は、d-blockクラスを付与してエラーメッセージを表示させ、そうでない場合は、d-noneを付与して非表示にしています。

2つのクラスはどちらもbootstrapが用意しているクラスです。

d-block・・・display: block;
d-none・・・display: none;

最後に

以上がBootstrap4 バリデーションエラーの表示方法でした!
思った以上に時間が掛かってしまったのですが、正常に動作した時の喜びは、その疲れを吹き飛ばしますね笑
これからも色んなことに挑戦し、学んだことを投稿していきたいと思います!!

間違っている箇所や分かりづらい箇所が多々あるかと思います。
その際は、気軽にコメントいただけれると幸いです。

最後までご覧いただき、ありがとうございました!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0