今回は文字列を入力して部分一致検索、プルダウンメニューから選択して検索を行う機能を実装します。具体的には下記の画面でユーザ名、棋力、好きな戦法による検索を行います。
Userモデルは以下のように name(ユーザ名)、stength(棋力)、tactics(好きな戦法)というカラムを定義します。
class User extends Authenticatable
{
protected $fillable = [
'name','strength','tactics',
];
}
コントローラは以下のようなindexメソッドを定義します。
class SearchController extends Controller
{
public function index(Request $request){
$query = User::query();
//$request->input()で検索時に入力した項目を取得します。
$search1 = $request->input('strength');
$search2 = $request->input('tactics');
$search3 = $request->input('name');
// プルダウンメニューで指定なし以外を選択した場合、$query->whereで選択した棋力と一致するカラムを取得します
if ($request->has('strength') && $search1 != ('指定なし')) {
$query->where('strength', $search1)->get();
}
// プルダウンメニューで指定なし以外を選択した場合、$query->whereで選択した好きな戦法と一致するカラムを取得します
if ($request->has('tactics') && $search2 != ('指定なし')) {
$query->where('tactics', $search2)->get();
}
// ユーザ名入力フォームで入力した文字列を含むカラムを取得します
if ($request->has('name') && $search3 != '') {
$query->where('name', 'like', '%'.$search3.'%')->get();
}
//ユーザを1ページにつき10件ずつ表示させます
$data = $query->paginate(10);
return view('users.search',[
'data' => $data
]);
}
}
検索ボタンを押したときのルーティングを以下のように記述します。
//検索ボタンを押すとコントローラのindexメソッドを実行します
Route::get('Search','SearchController@index')->name('search');
ユーザ検索ページのビューを以下のように記述します。
<div class="row">
<div class="col-sm-4">
<div class="text-center my-4">
<h3 class="brown border p-2">ユーザ検索</h3>
</div>
{!! Form::open(['route' => 'search', 'method' => 'get']) !!}
<div class="form-group">
{!! Form::label('text', 'ユーザ名:') !!}
{!! Form::text('name' ,'', ['class' => 'form-control', 'placeholder' => '指定なし'] ) !!}
</div>
<div class="form-group">
{!! Form::label('strength', '棋力:') !!}
{!! Form::select('strength', ['指定なし' => '指定なし'] + Config::get('strength.kiryoku') ,'指定なし') !!}
</div>
<div class="form-group">
{!! Form::label('tactics', '好きな戦法:') !!}
{!! Form::select('tactics', ['指定なし' => '指定なし'] + Config::get('tactics.senpou') , '指定なし') !!}
</div>
{!! Form::submit('検索', ['class' => 'btn btn-primary btn-block']) !!}
{!! Form::close() !!}
</div>
<div class="col-sm-8">
<div class="text-center my-4">
<h3 class="brown p-2">ユーザ一覧</h3>
</div>
<div class="container">
<!--検索ボタンが押された時に表示されます-->
@if(!empty($data))
<div class="my-2 p-0">
<div class="row border-bottom text-center">
<div class="col-sm-4">
<p>ユーザ名</p>
</div>
<div class="col-sm-4">
<p>棋力</p>
</div>
<div class="col-sm-4">
<p>好きな戦法</p>
</div>
</div>
//検索条件に一致したユーザを表示します
@foreach($data as $item)
<div class="row py-2 border-bottom text-center">
<div class="col-sm-4">
<a href="">{{ $item->name }}</a>
</div>
<div class="col-sm-4">
{{ $item->strength }}
</div>
<div class="col-sm-4">
{{ $item->tactics }}
</div>
</div>
@endforeach
</div>
{{ $data->appends(request()->input())->render('pagination::bootstrap-4') }}
@endif
</div>
</div>
</div>
ここでは以下のように、あらかじめconfigディレクトリにstrength.phpを作成して'kiryoku'という配列を定義しています。上記のビューではconfig::get('strength.kiryoku')でその配列を取得して、プルダウンメニューを作成しています。さらに['指定なし' => '指定なし'] + config::get('strength.kiryoku')
としてkiryoku配列に「指定なし」という要素を追加しています。
config/strength.php
<?php
return array(
'kiryoku' => array(
'10級' => '10級',
'9級' => '9級',
'8級' => '8級',
'7級' => '7級',
'6級' => '6級',
'5級' => '5級',
'4級' => '4級',
'3級' => '3級',
'2級' => '2級',
'1級' => '1級',
'初段' => '初段',
'二段' => '二段',
'三段' => '三段',
'四段' => '四段',
'五段' => '五段',
'六段' => '六段',
),
);
?>
config::get('tactics.senpou')も同様です。
config/tactics.php
<?php
return array(
'senpou' => array(
'角換わり' => '角換わり',
'矢倉' => '矢倉',
'相掛かり' => '相掛かり',
'横歩取り' => '横歩取り',
'向かい飛車' => '向かい飛車',
'三間飛車' => '三間飛車',
'四間飛車' => '四間飛車',
'中飛車' => '中飛車'
),
);
?>
ユーザ名のみで検索すると、以下のように正しく表示されました。
また棋力、好きな戦法で検索した場合も、以下のように正しく表示されました。
今回の検索機能のポイントは、コントローラの$request->input
メソッドと$query->where
メソッドかなと思いました。あとプルダウンメニューの実装はconfigファイルを使用しましたが、意外と躓きました。プルダウンメニューはほかの方法でより簡単に実装できるのかもしれません。