概要
バリデーションエラーや登録成功などのメッセージを一時的に表示する方法を整理する。
ダイアログによりブラウザー表示領域とは別に表示する方法と、表示領域にメッセージを出して動的に消去する方法の2つ。
エラー・成功メッセージの登録
以下のような例で考えていく。
- GETリクエストから表示用コントローラー・アクションにルーティング
- アクションからフォームを含むページを呼び出す
- フォームにユーザー名とメールアドレスの入力テキストボックスを配置
1 2 3 4 5 6 |
<form method="post"> @csrf <p><input type="text" name="name" placeholder="ユーザー名10文字以内"></p> <p><input type="text" name="email" placeholder="***@***"></p> <input type="submit" value="送信"> </form> |
- 送信ボタンが押された場合のPOSTに対して、バリデーション用コントローラー・アクションにルーティング
- バリデーション用アクションでは、ユーザー名とメールアドレスのバリデーションを記述
- バリデーション結果が妥当な場合は
flash()
で成功メッセージを登録 - バリデーション結果が妥当でない場合は、それ以降は実行されず
$errors
に結果が保存される
- バリデーション結果が妥当な場合は
- いずれの場合も元のGETルートにリダイレクトされる
1 2 3 4 5 6 7 8 9 10 |
public function flashResult(Request $request) { $request->validate([ 'name' => ['required', 'max:10'], 'email' => ['required', 'email'], ]); session()->flash('success', '正しく入力されました'); return redirect('/flash_sample'); } |
状況に応じて登録された/空のままの$errors
やflash
に対して、ビュー側で表示する。
ダイアログ表示
$errors
やflash
をダイアログで表示する方法。
ビューのhead要素内で、これらの状態に応じたメッセージを生成し、Javascriptのalert
の引数に渡している。
複数のエラーメッセージを改行文字を挟んでつなげるのに、PHPのinplode()
関数を使っている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>{{ $title }}</title> <script> @if ($errors->any()) alert("{{ implode('\n', $errors->all()) }}"); @elseif (session()->has('success')) alert("{{ session()->get('success') }}"); @endif </script> </head> <body> ..... </body> </html> |
スライドアップによる一時表示
エラーや成功メッセージをブラウザーの上部などに表示し、一定時間後にそれをスライドアップなどで消去する。
メッセージ表示領域の設定と、Javascriptによる動的な消去の2段階で整理する。
メッセージ表示エリアの設定
ビューのbody
要素最上部で、ディレクティブによってメッセージ表示領域を動的に生成している。その際に、エラー/成功に応じたクラスを要素に設定している。
$errors->any()
でエラーが登録されていれば、エラー表示領域を生成session()->has()
で成功メッセージが登録されていれば成功メッセージ表示領域を生成
ビューのhead
要素内で、エラーメッセージ領域/成功メッセージ領域それぞれのクラスに応じたスタイルを設定している。
なお、エラーメッセージは複数のメッセージを改行で表示させたいので、PHPのImplode()
関数で区切りを<br>
としたうえで{!! ... !!}
で囲んでエスケープを抑制している。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <style> .error { padding: 0.5em 1em 0.5em 1em; background-color: #fcc; } .success { padding: 0.5em 1em 0.5em 1em; background-color: #9df; } </style> <title>{{ $title }}</title> </head> <body> @if ($errors->any()) {{-- エラーメッセージ --}} <div class="error"> {!! implode('<br>', $errors->all()) !!} </div> @elseif (session()->has('success')) {{-- 成功メッセージ --}} <div class="success"> {{ session()->get('success') }} </div> @endif ..... </body> </html> |
メッセージ表示エリアの消去
エラー/成功のクラスに対して、JQueryでこれらをスライドアップして消去するスクリプトを追加する。
- 5行目でJQueryをCDNで読み込み
script
要素内でスライドアップの動作を定義
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <script src="https://code.jquery.com/jquery-3.5.0.min.js"></script> <script> window.setTimeout(() => { $(".error").slideUp(); $(".success").slideUp(); }, 1500); </script> ..... </head> <body> ..... </body> </html> |