Laravelのバリデーションエラーをview(blade)で表示する。具体例とともに解説

バリデーションエラー view(blade)で表示させてみる バリデーション
※当サイトはアフィリエイト広告を掲載しています。

Laravelでバリデーションエラーが発生した際、それを表示させるのはviewの役目です。そのうち最も一般的と思われるのが、デフォルトで採用されるbladeです。

本ページでは、そんなbladeを使用して、エラーメッセージを表示させる方法を具体例を交えてご紹介します。

実際のWebアプリケーションでもエラーの見せ方は避けては通れません。本ページではこんなこともできるよ!という例をいろいろと改造しながらやっていきます。

具体例ではなく、マニュアル的に読みたい方は本ページではなく、以下ページをご覧ください。

Laravelでは、VueやReactを使うことも可能です。一通り標準的な解説が終わり次第、当サイトでも取り扱おうと思います。

前提条件

法人のお問い合せフォームなどによくある条件で、簡素な例としてイメージしました。

バリデーション設定

FormRequestを継承した、InquiryRequestにてバリデーションを設定しています。正直、この辺はLaravel初心者さんは分からなくてもOK。

なぜならこのページの焦点となるのは、エラーの表示だからです(最悪、分からなくても良いです)。

namespace App\Http\Requests\Contact;

use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Contracts\Validation\Validator;

class InquiryRequest extends FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     */
    public function authorize(): bool
    {
        return true;
    }

    /**
     * バリデーションルールを定義
     *
     * @return array
     */
    public function rules(): array
    {
        return [
          'name'        => 'required|max:20',
          'furigana'    => 'max:20',
          'tel'         => 'nullable|regex:/^[0-9]{2,4}-[0-9]{2,4}-[0-9]{3,4}$/',
          'email'       => 'required|email',
          'body'        => 'required|max:1000',
          'is_accepted' => 'accepted',
        ];
    }

    /**
     * バリデーションエラーメッセージを定義
     *
     * @return array
     */
    public function messages(): array
    {
        return [
          'name.required'  => ':attributeは必須項目です。',
          'name.max'       => ':attributeは最大:max文字以内で入力してください。',
          'furigana.max'   => ':attributeは最大:max文字以内で入力してください。',
          'tel.regex'      => ':attributeはハイフンをいれた数字でご入力ください。',
          'email.required' => ':attributeは必須項目です。',
          'email.email'    => ':attributeを正しく入力してください。',
          'body.required'  => ':attributeは必須項目です。',
          'body.max'       => ':attributeは最大:max文字以内で入力してください。',
          'is_accepted.accepted' => ':attributeにチェックをつけてください。',
        ];
    }

    /**
     * カスタム属性名を定義
     *
     * @return array
     */
    public function attributes(): array
    {
        return [
          'name' => 'お名前',
          'furigana' => 'ふりがな',
          'tel' => '電話番号',
          'email' => 'Email',
          'body' => 'お問い合せ内容',
          'is_accepted' => 'ご利用規約に同意する',
        ];
    }
}
Lara
Lara

名前などの各項目に、最低限のバリデーションルールが設定されているとお考えください。

標準的なエラーを表示する

コード

あえてシンプルなview(blade)にしました。いろいろあると逆に分かりづらいので、お名前以外は省略しています。

<form action="{{ url('/contact/inquiry') }}" method="post">
    @csrf
    <dl class="form">
      <div class="form-item">
        <dt>お名前
          <span class="form-required">必須</span>
        </dt>
        <dd>
          <input type="text" name="name" class="form-input" value="{{ old('name') }}">
          @error('name')
          <div class="error"><span>{{ $message }}</span></div>
          @enderror
        </dd>
      </div>
      <!-- ~省略~ -->
    </dl>
    <div>
      <button type="submit">送信する</button>
    </div>
  </form>

実際のエラー画面

先ほどのコードでのエラー時のスクリーンショットです。フォーム項目のすぐ下にエラーを表示しているのがわかります(簡単にCSSで色を分かりやすくしています)。

コード解説

もう少しコードをクローズアップしてみましょう。

        <dt>お名前
          <span class="form-required">必須</span>
        </dt>
        <dd>
          <input type="text" name="name" class="form-input" value="{{ old('name') }}">
          @error('name')
          <div class="error"><span>{{ $message }}</span></div>
          @enderror
        </dd>

6行目でバリデーションルールに定義した'name'にエラーがあるか判定しています。あれば7行目を表示し、なければ7行目をとばします。

7行目には{{ $message }}という記載がありますが、これによりこの項目で発生しているエラー内容を表示出来るのです。

複数のエラーが発生している場合、最初のエラーのみ表示されます。

つまり、以下の様にたったこれだけのことです。

          @error('name')
          エラーがあるときのみ表示されるメッセージ。
          {{ $message }}部分でエラー内容が表示されます。
          @enderror

@error('name')の、'name'部分はバリデーションする対象によって変わります。

対して{{ $message }}は常にこれでOK。

ですのでコピペして他の項目用のエラーとして貼り付けるなら、'name'部分を変えれば動作します。

エラーを目立たせるためにしていること

以下の様に、エラーメッセージにclass="error"のようにクラス名を付けておけば、今回のようにCSSでエラーの色を変えられます。

          @error('name')
          <div class="error"><span>{{ $message }}</span></div>
          @enderror

今回は以下の様にCSSを設定しています。

    .error span {
      background-color: #f0ea94;
      color: #ff0000;
      font-weight: bold;
    }

背景色の設定、文字色の設定、太字設定となりますね。

さらに強調させる

エラーになった箇所を、強調表示させるようなことも、実務ではよくありますね。それを実現してみたいと思います。

コード

Laravelのミドルウェアにより、自動でセットしてくれる$errorsという変数を使うことが可能です。

この変数は、Illuminate\Support\MessageBagのインスタンスであり、エラー表示に関する様々なメソッドをサポートしています。

ここでは引数で与えたフォーム要素にエラーがあるかどうかをBoolで返す、$errors->has('name')というメソッドを使います。

        <dt>お名前
          <span class="form-required">必須</span>
        </dt>
        <dd>
          <input type="text" name="name"
            class="form-input{{ $errors->has('name')? ' error' : '' }}"
            value="{{ old('name') }}">
          @error('name')
          <div class="error"><span>{{ $message }}</span></div>
          @enderror
        </dd>

実際のエラー画面

スクリーンショットはこんな感じです。入力欄に赤線と背景に色をつけました。

コード解説

<input type="text" name="name"
   class="form-input{{ $errors->has('name')? ' error' : '' }}"
   value="{{ old('name') }}">

{{ $errors->has('name')? ' error' : '' }}部分で三項演算子を使っています。

ここでの三項演算子部分は、$errors->has('name')true、つまりエラーだったら、' error'falseだったら空文字の''を返します。

三項演算子の書式は以下です。
bool ? 'A' : 'B'

すなわち'name'にエラーがあれば、以下のHTMLが生成されます。

<input type="text" name="name" class="form-input error" value="">

そうでない場合は以下のHTMLが生成されます。

<input type="text" name="name" class="form-input" value="">

そのため以下のようなCSSを定義しておけば、エラー時のみ見栄えが変わるのです。

    .form-input.error{
      border:2px solid #ff0000;
      background-color:#eee;
    }

エラーは最上部に出したい

根強く昔からあるのが、エラーの情報は最上部に全て出したいというケースです。こちらも、これまでの修正から続ける形で実装してみたいと思います。

コード

フォームの始まり部分を修正します。

  <form action="{{ url('/contact/inquiry') }}" method="post">
    @csrf
    @if ($errors->any())
    <div class="error-index">
      <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
    <!-- ~省略~ -->

実際のエラー画面

以下がスクリーンショットですが、ちょっとくどいですね。これを出すなら、下の方のエラーは不要かと思います。

コード解説

    @if ($errors->any())
    <div class="error-index">
      <ul>
        @foreach ($errors->all() as $error)
        <li>{{ $error }}</li>
        @endforeach
      </ul>
    </div>
    @endif

1行目で、いずれかにエラーがあるか判定します。なければ9行目以降まで無視されます。

エラーがある場合、4行目~6行目までforeachループを回し、エラーを1つずつ表示しています。

最終系

ここでの最終系とします。上も下も詳細にエラーを出すのはちょっとくどいので、上はエラーがあった旨だけ表示させて終わりとしたいと思います。

実際のエラー画面

最後はスクリーンショットを見た方が早いです。

コード解説

先ほどいじったところがくどかったので、個別のエラーは出さずに、簡単にとどめることにしました。

<form action="{{ url('/contact/inquiry') }}" method="post">
    @csrf
    @if ($errors->any())
    <div class="error-index">
     <p>⚠️エラーが発生しました。以下の赤文字のエラー箇所をご確認ください。</p>
    </div>
    @endif
    <dl class="form">

先ほどと比べ、プログラム的な部分はいじっていません。単にHTMLでエラーメッセージを表示させただけです。3行目~7行目の間ですね。

しいて挙げる部分があるとすれば、5行目のpタグ開始直後は、UTF-8で使える警告の絵文字です。あくまで簡易的なものなので、実際にはSVGなどで作ってあげると良いでしょう。

まとめ

今回はステップ by ステップ形式で、フォームのエラー表示を変えていきました。この全てを使う……というわけではなく、あなたのウェブアプリケーションに適したエラーメッセージを出すのに役立てていただければと思います。

本ページのコードを利用した実例は、以下のページで解説していますので興味のある方はご覧ください。

本ページではPHP/Laravelの他、HTML/CSSなどの技術も使用しました。PHP/Laravel使いは、HTML/CSSも理解しておくと仕事の幅が広がりますよ。

最後になりますが、この例のフォームエラーのCSSデザインは説明用に簡単に作っています。実際にはサイトの表現にあった色使いなどをしてあげると、よりクールなWebアプリケーションに近づくでしょう。

Lara
Lara

デザインも……となると大変ですが、フリーランスのエンジニアになりたい方は、そのあたりも学んでおくとベターですね。

コメント

タイトルとURLをコピーしました