###やりたいこと
Laravelでは、何かの一覧を表示し、かつ、paginate(num)とするだけで、ページングできて便利。ただ、何かしらの一覧には「検索」機能が必須となるが、パラメータの持ち回りや、パラメータが複数(動的)の場合どうするかをまとめる。
###ポイント
ポイントは、2つ。
・検索keyword(パラメータ)の持ち回り
・動的クエリの生成
では、どうするか見てみます。
####パラメータの持ち回り
ページリンクにて、検索Keywordを持ちまわる必要があるが、それは、$model->appends()->render()を利用する。例えばこんな感じ。
ここでは、nameとemailというkeywordを持ちまわっている。
{!!$members->appends(['name'=>$name,'email'=>$email])->render()!!}}
そもそも、controllerからviewへの値の持ち回りは、view('list')->with('email',$email)->with('name',$name);などとして、withチェーンか、配列等で持ちまわる。
####動的クエリの生成
パラメータが複数の場合は、どのように動的にクエリを生成するか?。ちょっと悩むが、わかれば簡単。
//$query = new Member;とも書ける。
$query = Mmeber::query();
$query->where('name',$name);
$query->where('email',$email);
$members = $query->paginate(10);
こう書くことで、条件をappendしていける。当然、where以外の条件も追加できる。
パラメータが動的(あったり、なかったり)な場合は、if(empty($name)){}などをかまし、必要な条件だけを追加するようにする。
ここでは、nameとemailを別々に受け取っているが、1つのkeywordをspaceでsplitすりょうな場合でも基本は同じ。
###その他のソースも載せておく
大前提として、DBにid,name,emailのカラムを有するテーブルが必要。で、eloquentを使うので、Memberモデルを書いておく。
####Model
テーブルを指定し、timestampsは無いのでfalseに。
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class Member extends Model {
//
protected $table = 'members';
public $timestamps = false;
}
####Route
HogeControllerのindexで受ける。
Route::get('/','HogeController@index');
####Controller
index()のみ。
HogeController.php
public function index()
{
//値を取得
$name = Input::get('name');
$email = Input::get('email');
//query
$query = Member::query();
//もしnameがあれば
if(!empty($name)){
$query->where('name','like','%'.$name.'%');
}
//もしemailがあれば
if(!empty($email)){
$query->where('email','like','%'.$email.'%');
}
//paginate
$members = $query->paginate(10);
//値を返す
//name,emailを返す
return view('list')->with('members',$members)->with('name',$name)->with('email',$email);
}
####View
#####master
paginateは、bootstrapに合わせたtag,cssを出力するので、bootstrapを読み込む。
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
<title>
@yield('title')
</title>
</head>
<body>
@yield('body')
</body>
</html>
#####list
検索窓付き、一覧表示。
@extends('master')
@section('title')
list
@stop
@section('body')
<form method="get" action="./">
<input type="text" name="name">
<input type="text" name="email">
<input type="submit" value="search">
<input type="hidden" name="_token" value="{{csrf_token()}}">
</form>
@foreach($members as $member)
{{$member->name." ".$member->email}}<br>
@endforeach
<!-- name,emailがあれば、パラメータに含める -->
{!!$members->appends(['name'=>$name,'email'=>$email])->render()!!}
@stop
とりあえず、こんな感じ。
###発展
実際には、検索時のmethodはPOSTにしたいとか、URLいじられたときのエラー処理などが必要ですが、ひとまず割愛。