LoginSignup
3
2

More than 3 years have passed since last update.

Laravelでデータベースから検索した値をペジネーションを使って表示させる

Last updated at Posted at 2019-07-15

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を)

/routes/web.php
Route::get('/form', 'FormController@index');
Route::get('/booklist', 'FormController@booklist');

コントローラーを作ります。

/Http/Controller/FormController.php

<?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モデルを。

データベース関連の設定は出来ているものとして進みます!もしデータベース系のエラーが出る時は別で調べてください!

/app/Booksearch.php

<?php

namespace App;

use Illuminate\Database\Eloquent\Model; //忘れずに!

class Booksearch extends Model
{
protected $table = 'default.book'; //defaultデータベースのbookテーブルなので定義しておきます。
}

実際に表示させるページ

デザインは一切していないので各自行ってください。

まずは検索フォームのページ。
特に難しいことはしてないです。

/views/form.blade.php
<!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>

一覧を表示させるページ

/views/booklist.blade.php
<!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便利ですね!

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2