Laravelでチェックボックスを使用した検索フォームの作り方

## サンプル
### 検索画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/d1ca1c43-5ede-4260-49ef-0847e880d5d4.png)

### 検索結果画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218398/28c4a18b-f897-cbe6-54d8-81095ecc007a.png)


## コード

### ルーティング処理

```\routes\web.php
Route::get('/search/','Search\SearchController@index');
Route::post('/search/result/','Search\SearchController@result');
```

### コントローラー
- `index`: 検索画面の処理
- `result`: 検索結果画面の処理

```\app\Http\Controllers\Search\SearchController.php

<?php


namespace App\Http\Controllers\Search;

use DB;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class SearchController extends Controller
{
    public $form_data = [
        ['名前', 'checkbox[name]', 'name'],
        ['メールアドレス', 'checkbox[email]', 'email'],
        ['コメント', 'checkbox[comment]', 'comment'],        
    ];

    public function index()
    {
        return view('search/index',[
            'form_data' => $this->form_data,
        ]);
    }

    public function result(Request $request)
    {

        $validation_array = [
            'keyword' => 'required',
            'checkbox' => 'required',
        ];

        $validator = Validator::make($request->all(), $validation_array);

        if ($validator->fails()) {
            return redirect('/search/')
                        ->withErrors($validator)
                        ->withInput();
        };

        $checkbox_arrary = [];
        foreach ($request->input('checkbox') as $value){
            $checkbox_arrary[] = $value;
        }

        $user_data = DB::table('users');

        if(in_array('name', $checkbox_arrary)){
            $user_data->where('name', 'like', '%'.$request->input('keyword').'%');
        }
        if(in_array('email', $checkbox_arrary)){
            $user_data->where('email', 'like', '%'.$request->input('keyword').'%');
        }
        if(in_array('comment', $checkbox_arrary)){
            $user_data->where('comment', 'like', '%'.$request->input('keyword').'%');
        }

        $result = $user_data->get();

        return view('/search/result',[
            'search_data' => $result,
        ]);
    }

}


```


### View

```\resources\views\search\index(.blade).php
<form method="POST" action="/search/result">
    <table>
        <tr>
            <th>検索カテゴリ</th>
            @foreach($form_data as $value)
                <td>
                    <input name="{{ $value[1] }}" type="checkbox" value="{{ $value[2] }}" {{ old($value[1]) == $value[2] ? 'checked' : '' }}>
                    <p>{{ $value[0] }}</p>
                </td>
                @if($errors->has('checkbox'))
                    <p style="color: red;">{{ $errors->first('checkbox') }}</p>
                @endif 
            @endforeach                               
        </tr>
        <tr>
            <th>検索ワード</th>
            <td><input name="keyword" type="text" value="{{ old('keyword') }}"></td>
            @if($errors->has('keyword'))
                    <p style="color: red;">{{ $errors->first('keyword') }}</p>
            @endif 
        </tr>
        <tr>
            <button type="submit">検索する</button>
        </tr>
    </table>
    @csrf
</form>
```

```\resources\views\search\result(.blade).php
<div>
    <table>
        <tr>
            <th>名前</th>
            <th>メールアドレス</th>
            <th>コメント</th>                                
        </tr>
        @foreach($search_data as $value)
        <tr>
            <td>{{ $value->name }}</td>
            <td>{{ $value->email}}</td>
            <td>{{ $value->comment }}</td>
        </tr>
        @endforeach
    </table>
    <a href="/search/">検索画面に戻る</a>
</div>
```


## ポイント
### チェックボックスのバリデーション

```\resources\views\search\index(.blade).php
// foreachでデータが渡された後
<input name="checkbox[name]" type="checkbox" value="name" {{ old(checkbox[name]) == 'name' ? 'checked' : '' }}>
<input name="checkbox[email]" type="checkbox" value="email" {{ old(checkbox[email]) == 'email' ? 'checked' : '' }}>
<input name="checkbox[comment]" type="checkbox" value="comment" {{ old(checkbox[comment]) == 'comment' ? 'checked' : '' }}>
```

`input`の`name`属性では、 **`checkbox[name]`のように配列で値を指定できる。**

```\app\Http\Controllers\Search\SearchController.php
$validation_array = [
    'keyword' => 'required',
    'checkbox' => 'required',
];
```

**配列名を`required`することで、チェックボックスのどれかにはチェックを入れること** をバリデーションできる。

### 検索処理

```\app\Http\Controllers\Search\SearchController.php
$checkbox_arrary = [];
foreach ($request->input('checkbox') as $value){
    $checkbox_arrary[] = $value;
}
```

`$request->input('checkbox[name]')` みたいな形で値を取り出せないので、`$request->input('checkbox')`を`foreach`にかけて別の配列に入れ直して、この後の処理で使えるようにする。


```\app\Http\Controllers\Search\SearchController.php
$user_data = DB::table('users');

if(in_array('name', $checkbox_arrary)){
    $user_data->where('name', 'like', '%'.$request->input('keyword').'%');
}
if(in_array('email', $checkbox_arrary)){
    $user_data->where('email', 'like', '%'.$request->input('keyword').'%');
}
if(in_array('comment', $checkbox_arrary)){
    $user_data->where('comment', 'like', '%'.$request->input('keyword').'%');
}

$result = $user_data->get();
```

**どのチェックボックスに値が入っていたかで`if`文をかけ、DBクエリで`where`を追加している。**
最後に`get()`することを忘れない。

## 参考記事
- [【Laravel】Bladeで@ifではなく三項演算子を使う - やんばるテック](https://blog.shonansurvivors.com/entry/laravel-ternary-operator)
- [クエリ・ビルダーを使ってwhere文節を追加するにはどうすればいいですか？（Laravel）](https://teratail.com/questions/2092)
- [Laravelでwhere検索する時、部分一致を用いても検索できない - Qiita](https://qiita.com/Lil_Ryo/items/f344fb84b59622a67b7b)
- [Laravelでのバリデーション（値チェック）の方法 - Qiita](https://qiita.com/shima0218/items/1320c82a060434330d71)
- [フォームのチェックボックスの値を取得する | 僕のウェブデザイナー忘備録](https://iklabo.net/2016/01/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0/htmlcss/post-198/)