【laravel】1つ目のセレクトボックスの値に応じて2つ目のセレクトボックスの候補を変えるプログラム(備忘録)

## はじめに
作成や編集においてプルダウンを配置することは少なくないと思う。
また場合に応じて、1つ目の選択肢次第で2つ目の候補を変えたいと考えることがある。
今回はそんな実装。

## 前提
laravel9
php8

## Controllerを編集する
```trRecordController/.php
    public function create() {

        $trParts = TrPart::pluck('part_name', 'id');
        $trSettypes = TrSettype::pluck('set_type', 'id');
        $trMenus = TrMenu::pluck('menu', 'id');
        $today = date("Y-m-d");
        return view('trrecords.create', compact(
            'trParts',
            'trSettypes',
            'trMenus',
            'today',
        ));

    }

    public function store(TrRecordRequest $request) {

        $validated = $request->safe()->only([
            'part',
            'menu',
            'set_type',
            'weight_first',
            'reps_first'
        ]);

        $trRecord = new TrRecord();
        $trRecord->user_id = Auth::id();
        $trRecord->fill($request->all());
        $trRecord->part = TrPart::find($validated['part'])->part_name;
        $trRecord->menu = TrMenu::find($validated['menu'])->menu;
        $trRecord->set_type = TrSettype::find($validated['set_type'])->set_type;
        $trRecord->save();

        return redirect()->route('trrecords.index')->with(
            'message', '登録が完了しました'
        );
    }
```
- 今回pluckメソッドを使って必要なカラムを指定してあげる。
- プルダウンで使いたいカラムの値はDBに事前に登録済み。それをビューで使ってあげる。

```WebApiController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\TrMenu;

class WebApiController extends Controller
{
    public function getTrainingMenu(Request $request) {
        $menuVal = $request['menu_val'];
        $trMenu = TrMenu::where('tr_part_id', $menuVal)->get();
        $result = [];
        foreach ($trMenu as $item) {
            $result[$item->id] = $item->menu;
        }
        return response()->json($result);
    }
}

```
- Jqueryからデータを受け取ってあげる
- json形式でデータを渡す

### View
```create.blade.php
            <div class="row mb-3">
                <label class="col-sm-2 col-form-label">Part</label>
                <div class="col-sm-10">
                    <select class="form-control" id="part_id" name="part">
                        <option value="" style="display: none;">選択してください</option>
                        @foreach ($trParts as $index => $name)
                            <option value="{{ $index }}" {{ old('part') === "$index" ? 'selected' : '' }}>{{ $name }}</option>
                        @endforeach
                    </select>
                    @error('part')
                        <li>{{$message}}</li>
                    @enderror
                </div>
            </div>
            <div class="row mb-3">
                <label class="col-sm-2 col-form-label">Menu</label>
                <div class="col-sm-10">
                    <select class="form-control" id="menu_id" name="menu">
                        <option value="" style="display: none;">選択してください</option>
                        @foreach ($trMenus as $index => $name)
                            <option value="{{ $index }}" {{ old('menu') === "$index" ? 'selected' : '' }} >{{ $name }}</option>
                        @endforeach
                    </select>
                    @error('menu')
                        <li>{{$message}}</li>
                    @enderror
                </div>
            </div>
```
- データベースからデータをとってきて、foreachで回してあげる
- `old`を使って値保持をする

```create.blade.php
<script type="text/javascript">
// セレクトボックスの連動
// 親カテゴリのselect要素が変更になるとイベントが発生
$('#part_id').change(function () {
    var part_val = $(this).val();

    $.ajax({
        headers: {
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        url: '/webapi',
        type: 'GET',
        data: {'menu_val' : part_val},
        datatype: 'json',
    })
    .done(function(data) {
        // 子カテゴリのoptionを一旦削除
        $('#menu_id option').remove();
        // DBから受け取ったデータを子カテゴリのoptionにセット
        console.log(data);
        $.each(data, function(key, value) {
            $('#menu_id').append($('<option>').text(value).attr('value', key));
        });
    })
    .fail(function() {
        console.log('失敗');
    });

});
</script>

```

これで1つ目のプルダウンの選択肢に応じて、2つ目に出すプルダウンの選択肢を変えることができる。

以上。