【Laravel 5.8.13+】@errorをBootstrap3/4・Tailwind CSS・Semantic UIで使った実例

さてさて、前回【Laravel 6.2+】パスワードの再確認機能をつくるという記事をお届けしましたが、この中で「そういえばいつか紹介しようと思っていたのに忘れていた」という新機能(比較的ですが)がありました。

それは、

Bladeテンプレートの中で使えるようになった@errorディレクティブ

です。

これは、Laravel 5.8.13で追加されたもので、以下のようにシンプルに「指定した名前のエラーがあれば表示される」というものです。

@error('email')
    <!-- emailにエラーがあれば、ここが表示される -->
    {{ $message }}
@enderror

使い方はとてもシンプルなのでこれ以上説明する必要はないと思いますが、じゃあ、この@errorを以下の有名CSSフレームワークと一緒に使う場合はどうなるのか、ということが気になったので今回はそれぞれの使い方をまとめてみました。

  • Bootstrap 4
  • Bootstrap 3
  • Tailwind CSS
  • Semantic UI

ぜひ皆さんのお役に立てると嬉しいです😊✨

開発環境: Laravel 6.x

まずは準備

@error部分は送信内容にエラーがあった場合に表示される部分なので、先にバリデーションをつくっておくことにします。

もし、すでにお持ちの方は次の項目まで読み飛ばしてください。

ルートをつくる

ルートは、送信フォームとPOST送信する先の2つです。

Route::get('blade_error/create', 'BladeErrorController@create');
Route::post('blade_error', 'BladeErrorController@store');

コントローラーをつくる

次にコントローラーです。
以下のコマンドを実行してください。

php artisan make:controller BladeErrorController

作成されたapp/Http/Controllers/BladeErrorController.phpの中身は次のようにします。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class BladeErrorController extends Controller
{
    public function create() {

        return view('blade_error.create');

    }

    public function store(Request $request) {

        // バリデーション
        $request->validate([
            'email' => 'required|email'
        ]);

    }
}

ビュー

最後にビューです。
resources/views/blade_error/create.blade.phpというファイルをつくり、中身を以下のようにしてください。

<html>
<head>
</head>
<body style="padding:15px;">
    <form method="post" action="/blade_error">
        @csrf

        <!-- ここに各CSSフレームワークのフォームをつくる -->

    </form>
</body>
</html>

では、ここからが各CSSフレームワークを使ったフォームの実装です!

各CSSフレームワークで@errorをつかう実例

Bootstrap 4

<html>
<head>
    <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body style="padding:15px;">
    <form method="post" action="/blade_error">
        @csrf
        <!-- Bootstrap 4.3 -->
        <div class="form-group">
            <label>メールアドレス</label>
            <input name="email" type="text" class="form-control @error('email') is-invalid @enderror">
            @error('email')
            <div class="invalid-feedback">
                {{ $message }}
            </div>
            @enderror
        </div>
        <button class="btn btn-primary" type="submit">送信する</button>
    </form>
</body>
</html>

Bootstrap 4の場合は入力ボックスを赤線にするためのクラスとメッセージ本体を表示する2ヶ所が可変になります。

実際の表示はこうなります。

Bootstrap 3

<html>
<head>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>
<body style="padding:15px;">
    <form method="post" action="/blade_error">
        @csrf
        <!-- Bootstrap 3 -->
        <div class="form-group @error('email') has-error @enderror">
            <label>メールアドレス</label>
            <input type="text" class="form-control">
            @error('email')
                <span class="help-block">{{ $message }}</span>
            @enderror
        </div>
        <button class="btn btn-primary" type="submit">送信する</button>
    </form>
</body>
</html>

先ほどのBootstrap 4の場合と似ていますが、クラス名が違っているので注意してください。また、Bootstrap 3の場合は入力ボックスに直接クラス指定はしない形式になっています。

Tailwind CSS

<html>
<head>
    <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
</head>
<body style="padding:15px;">
    <form method="post" action="/blade_error">
        @csrf
        <!-- Tailwind CSS 1.0 -->
        <div>
            <label class="block text-gray-700 text-sm font-bold mb-2" for="password">
                メールアドレス
            </label>
            <input name="email" type="text" class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 mb-3 leading-tight focus:outline-none focus:shadow-outline @error('email') border-red-500 @enderror">
            @error('email')
                <p class="text-red-500 text-xs italic mb-3">{{ $message }}</p>
            @enderror
            <button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="submit">
                送信する
            </button>
        </div>
    </form>
</body>
</html>

Tailwind CSSは細かな設定を1つずつ重ねていく形式なので入力ボックスのクラスが多めになっていますが、基本的にはBootstrap 4と同じです。

Semantic UI

<html>
<head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui@2.4.2/dist/semantic.min.css">
</head>
<body style="padding:15px;">
    <form method="post" action="/blade_error">
        @csrf

        <!-- Semantic UI 2.4 -->
        <div class="ui form @error('email') error @enderror">
            <div class="field @error('email') error @enderror">
                <label>メールアドレス</label>
                <input name="email" type="text">
            </div>
            @error('email')
            <div class="ui error message">
                <p>{{ $message }}</p>
            </div>
            @enderror
            <button type="submit" class="ui submit button">送信する</button>
        </div>

    </form>
</body>
</html>

Semantic UIは他のCSSフレームワークとは少し違って、一番外側の要素と入力ボックスの外側の要素にそれぞれerrorというクラスが適用されるようにする必要があります。

ちなみに:エラーが発生した入力ボックスに自動スクロールする方法

例えば、ページをスクロールしないといけないぐらい多くの入力ボックスがあった場合、エラーが発生してもどこにエラーが発生したかが分かりにくかったりします。(ページ外の部分にエラーがあることもあるので)

そういった場合に以下のコードを使えば「ページの中で一番上にあるエラー」に自動スクロールしてくれるようになります。

<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
<script>

    // ページが読み込まれたら実行
    $(() => {

        let top = 0;

        $('.is-invalid').each((index, element) => {

            let newTop = $(element).parent().offset().top;

            if(top === 0 || top > newTop) {

                top = newTop;

            }

        });

        $('html, body').animate({
            scrollTop: top
        }, 'fast');

    });

</script>

実際にエラーを発生させるとこうなります。(スクロールが移動していることに注目してください)

これでユーザービリティが向上するかと思います😊

おわりに

ということで、今回はBladeの新しいディレクティブ@errorの使い方をCSSフレームワークを交えてご紹介しました。

もちろんいろんな書き方がありますが、コピペするだけでもある程度の入力フォームがつくれるので、ぜひ活用していただけると嬉しいです。

ちなみに、個人的な感想で言うと最近はフォーム送信でHTTPアクセスではなくAjaxを使っているので@errorはそれほど使わないかもしれないな、と感じました。

というのも、Ajaxでの送信だと「一緒にファイル送信する際にバリデーションで引っかかっても、そのままもう一度送信しなおせる」というのがユーザーにとって大きなメリットだと感じるからです。

つまり、通常通りHTTPで送信してしまってエラーが発生するとその度にまたファイルを選択してもらわないといけないのは、ユーザビリティとしてはあまりよろしくないと感じているんですね。

ただ、ちょっとしたフォームだけなら通常のフォーム送信で問題ないこともあると思うので、そこは臨機応変かもしれません。

ぜひ皆さんも機会があれば@errorを使ってみてくださいね。

ではでは〜!

この記事が役立ちましたらシェアお願いします😊✨