Laravelのペジネーションと検索フォームを使った簡単な蔵書検索サイトを作成してみます。
初心者の方に向けて書いた記事ですので色々クールじゃ無いとこもあるかもです。
基本事項
Laravel 5.7
PHP7.2
Mysql
defaultデータベースのbookテーブルを以下の内容で作ってます。
id
name …書籍名
author …著者名
day …発行日
今回は以下のファイルを使って蔵書検索を書籍名で行い別ページにて一覧を表示させる仕様にします。
form.blade.php //蔵書検索フォーム
booklist.blade.php //一覧表示
FormController.php //コントローラー
Booksearch.php//モデル
ルーティング
まずはroutes/web.phpにてルーティングします。
(わかってる人は::resourceを)
Route::get('/form', 'FormController@index');
Route::get('/booklist', 'FormController@booklist');
コントローラーを作ります。
<?php
namespace App\Http\Controllers; //名前空間
use Request; //値の受け渡しをするのでもちろん必要
use App\Booksearch; //Booksearchモデル(Eloquent) あとで作ります。
class FormController extends Controller {
public function index(){ //formにアクセスされたら単純にform.blade.phpを返します。あとで作ります。
return view('form');
}
public function booklist(Request $request){ //検索フォームから値を受け取って一覧表示をさせる処理とか。
$title = Request::get('title'); //GET送信された書籍名を受け取ります。
if ($title) { //書籍名が入力されてたらの処理
$item = Booksearch::where('name', 'LIKE', "%$title%")->simplePaginate(2);
//where()でBooksearchモデルを利用してテーブルのnameカラムが入力した書籍名の本を検索
//simplePaginate(表示数)でさらにペジネーションをするようにしています。前後ページだけを表示するsimplepaginateを今回使ってますが、1.2.3.4…とページ数を一気に表示させたいときはPaginateを使ってください。
}else { //書籍名が入力されていない時の処理
$item = Booksearch::select('*')->simplePaginate(2);
//書籍名がない時は全件表示させることにします。
$title='全件表示';
}
return view('booklist',['items' => $item])->with('title',$title);
//一覧のbooklist.blade.phpを表示させる時に$itemに格納された結果と検索ワードを渡してあげてます。
}
}
何回も出てきたBooksearchモデルを。
データベース関連の設定は出来ているものとして進みます!もしデータベース系のエラーが出る時は別で調べてください!
<?php
namespace App;
use Illuminate\Database\Eloquent\Model; //忘れずに!
class Booksearch extends Model
{
protected $table = 'default.book'; //defaultデータベースのbookテーブルなので定義しておきます。
}
実際に表示させるページ
デザインは一切していないので各自行ってください。
まずは検索フォームのページ。
特に難しいことはしてないです。
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>書籍検索</title>
<body>
<h2>蔵書検索</h2>
<form method="GET" action="/booklist"> //booklistへ本の名前を飛ばしてます
<input type="text" name="title">
<input type="submit" value="検索">
</form>
</body>
</html>
一覧を表示させるページ
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>書籍検索</title>
<body>
<h2>蔵書検索結果</h2>
<p>検索キーワード:{{$title}}</p>
@if(!$items->isEmpty()) //検索結果があるか確認してある時の処理(@emptyじゃオブジェクトなので無理です)
<table>
<tr><th>本の名前</th><th>著者名</th><th>出版日</th></tr>
@foreach($items as $item) //$itemsでコントローラーから渡された値を@foreachで表示します。
<tr>
<td>{{$item->name}}</td>
<td>{{$item->author}}</td>
<td>{{$item->day}}</td>
</tr>
@endforeach
{{ $items->appends(Request::only('title'))->links()}} //ここが肝です。下記で説明します。
</table>
@else //検索結果があるか確認して無い時の処理
<p>該当する書籍は存在しません</p>
<h2>蔵書検索</h2>
<form method="GET" action="/booklist">
<input type="text" name="title">
<input type="submit" value="検索">
</form>
@endif
###肝の部分
ペジネーションを使う時に
前後のページへのリンクを表示させる際は、
{{ $items->links()}}
を使いますが、これでは最初のページはしっかり条件にあったものだけ表示されますが、次ページに行ってしまうと
検索のために必要なGETパラメーター(検索ワード)が維持できません。
そこで、リンク自体にパラメーターを持たせてあげます。
{{ $items->appends(Request::only('title'))->links()}}
これでページ遷移してもちゃんとした検索結果のまま表示してくれます!
Laravel便利ですね!