LaravelでSelect2とBootstrap4を使って、バリデーションエラー時に赤枠で囲む


やりたいこと

Laravelでバリデーションエラー時に赤枠で囲んでエラーであることを示したい

やり方

セットアップ

まずはSelect2インストール
CDN使うならとばします

npm i select2

select2を適用する
適当にbladeにselect作って適当なクラスを作りました

hoge.blade.php

<select name="hoge" class="js-attachSelect2">
    <option value=1>テスト1</option>
    <option value=2>テスト2</option>
    <option value=3>テスト3</option>
</select>

resources/js/assets/app.jsと同階層に適当なjsファイル作成してapp.jsで読み込みます

app.js
import './bootstrap';

import './select2Test';

select2の適用

select2Test.js
import select2 from "select2";
$(function(){
    $('.js-attachSelect2').select2();
})

ここで、ようやくバリデーションエラー時の対応を書いていきます
普通ならこれで、bootstrapの赤枠が表示されますが
一瞬表示されて、select2が適用され見えなくなります

hoge.blade.php

<select name="hoge"
        class="js-attachSelect2 @error('hoge') is-invalid @enderror">
    <option value=1>テスト1</option>
    <option value=2>テスト2</option>
    <option value=3>テスト3</option>
</select>

selectの一つ親要素にエラー表示のクラスをつけるとうまく表示されます
bootstrap4だとis-invalid

hoge.blade.php
<div class="@error('hoge') is-invalid @enderror">
     <select name="hoge" class="js-attachSelect2">
         <option value=1>テスト1</option>
         <option value=2>テスト2</option>
         <option value=3>テスト3</option>
     </select>
</div>

これで赤枠が表示されます。
select2側でデフォルトで色が定義されてるのですが、bootstrapより濃いので修正します

app.scss
.is-invalid {
    .select2-container--focus .select2-selection,
    .select2-container--open .select2-selection {
        -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
        box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;
        border-color: #ff0906;
    }
    .select2-dropdown,
    .select2-selection {
        border-color: #ff0906;
    }
}

でbootstrapっぽい色になった。