[Laravel]ページネーション(Pagination)について(カスタマイズするには)

laravel

Laravelのページネーションを使用したり、カスタマイズしたページネーションを実装したりしたことがあるので、思い出しながら復習してみます!

そもそもページネーションって?

Googleの下にあるこれです!

長い一覧のページを分割して、リンクを並べてるやつですね😀

Laravelでページネーションを使うには?

コントローラでpaginateを使って呼び出す

Modelからデータを読み出すときにpaginateを使うと LengthAwarePaginatorの形式で返ってくるので、それをviewに渡して使うといいです。
下記が作った掲示板のコードの一部で、一覧をコントローラから渡しているところです。

$board = new Board();
$board_list = $board->orderBy("created_at", "desc")->paginate(env("PAGE_MAX_LIMIT"));

return view('top_list', ['board_list' => $board_list]);

paginateの第一引数に表示したい一覧の数を指定します。
board_listは下記のような感じで返ってきます。

bladeに渡したらこんな感じで使う

ページネーションのリンクを表示するには、こんな感じでlinks()を呼び出すとリンクが出力されます。リンクを押すとURLパラメータにpage=xがついてきて、押したリンクのページを表示してくれます。

<div class="mt-1 mb-1 row justify-content-center">
    {{ $board_list->links() }}
</div>

ページのアイテムの内容はforeachでループして、それぞれのプロパティにアクセスすると取得できます!
すごく簡単に実装できていいですね😙

@foreach ($board_list as $board)
    <li class="list-group-item">
        <div class=" d-flex justify-content-between">
            <a href="{{ route('detail.index', ["id" => $board->id]) }}"><h4>{{ $board->title }}</h4></a>
            <small class="text-secondary">{{ date_format($board->created_at, 'Y/m/d') }}</small>
        </div>
        @if(strlen($board->about_text) <= 100)
            <p class="mb-1">{{ $board->about_text }}</p>
        @else
            <p class="mb-1">{{ substr($board->about_text,0,100) }}...</p>
        @endif
        <small class="text-secondary">投稿者:{{ $board->user_name }}</small>
    </li>
@endforeach

ページネーションをカスタマイズするには?

ちょっと業務で、取ってきたcollectionのリストをゴニョゴニョマージしたり、手を加えてページネーションする必要が出てきたことがありました。
そんな時はLengthAwarePaginatorをnewしてページネーションを作ります。。

表示データ用意

$board = collect([
    new Board([
        'id' => 1,
        'title' => "aaa",
        'user_name' => "aaa",
        'about_text' => "aaa",
        'password' => "aaa",
        'created_at' => Carbon::now()
    ]),
    new Board([
        'id' => 2,
        'title' => "bbb",
        'user_name' => "bbb",
        'about_text' => "bbb",
        'password' => "bbb",
        'created_at' => Carbon::now()
    ]),
    new Board([
        'id' => 3,
        'title' => "ccc",
        'user_name' => "ccc",
        'about_text' => "ccc",
        'password' => "ccc",
        'created_at' => Carbon::now()
    ])]
);

最初にテスト用にデータを上記のように用意しました。

LengthAwarePaginatorでページネーション作成

LengthAwarePaginatorをnewして新しくページネーションを作りました。

$show_item = $board->chunk(1);

$board_list = new LengthAwarePaginator(
    $show_item->get($request->page - 1),
    count($board),
    1,
    $request->page
);

今回は3つコレクションを作って、1件ずつ表示するようにしました。
まずcollectionで作ったデータを1ページに1つのデータのみ表示させるよう分割します。

その後にLengthAwarePaginatorをnewして引数にデータを渡します。

引数で渡すものが下記になります。
・現在のページに表示するデータ
・データの総件数
・1ページに表示する数
・現在のページ番号

$request->pageでページ番号を受け取るので、処理するコントローラでもRequestを受け取らないといけないので注意が必要です。

動作確認

こんな感じで表示されました😃

カスタマイズするときにハマったところ

ページネーションのurlリンク先を変えたい

カスタマイズしたらリンクのURLが変なんだけど…

上記のような現象が発生して、viewで表示するページネーションのリンク先を変えたい場合は、
こんな感じで、LengthAwarePaginatorをnewしたオブジェクトからwithPathを呼び出して、現在のURLから相対的に定義します。

$board_list->withPath('hoge');

ページネーションリンクのgetパラメータにpage以外を付けたい

標準ではpageのパラメータしかないので、
検索状態を引き継いでページングしたい場合などは、下記のようにappendsを使ってパラメータを指定します。

Controllerの方にはこんな感じで書いておいて、

return view('top_list',[
    'pagenate_params' => [
        'param1' => 'hoge1',
        'param2' => 'hoge2',
        'param3' => 'hoge3',
    ],
]);

Viewのほうで、こうするといいです。

<div class="mt-1 mb-1 row justify-content-center">
    {{ $board_list->appends($pagenate_params)->links() }}
</div>

そうすると、こんな感じでパラメータが付加されます。

?page=2&param1=hoge1&param2=hoge2&param3=hoge3

コメント

タイトルとURLをコピーしました