
九保すこひです(フリーランスのITコンサルタント、エンジニア)
さてさて、前回【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
を使ってみてくださいね。
ではでは〜!