Posted at

laravel LengthAwarePaginatorで独自ペジネータ作成


はじめに

一番簡単な方法は、クエリビルダとEloquent queryへpaginateメソッドを使う方法ですが、

今回は、渡された配列を元にして、ペジネーションインスンタンスを作成して見ました。

誤った書き方や理解の仕方をしていた場合は、ご指摘いただきますと幸いです!

laravelのバージョンは5.6です。


出来上がりイメージ

よく見るデザインに仕上げてくれます。

alt


実装


  • getItemCollectionPaginator の引数にある$requestUrl$currentPageNo

    リクエストから現在のページとリクエストURLをController側で受け取ってきたものになります。


  • self::DISPLAY_ITEM_FOR_PAGENATION でリストの最大表示件数を決めています。


  • $this->itemRepositoryInterface->getItemCollection()->toArray()

    リポジトリパターンを利用し、画面に表示するデータを配列で全件取得しています。



  • そして本題であるLengthAwarePaginatorの引数には下記のデータを引数に与えます。


    • 1ページに表示するデータ※1

    • 全てのページを合わせた全件数

    • 1ページに表示する数

    • 現在のページ番号

    • ページネーション押下時のURL

    ( ※1 ぺジネーターに渡す結果の配列を自分で"slice"する必要があるため、

    array_chunkメソッドを使って配列を分割しています。)




TopService.php

    /**

* @param string $requestUrl
* @param string $currentPageNo
* @return LengthAwarePaginator
*/

public function getItemCollectionPaginator(string $requestUrl, string $currentPageNo = null): LengthAwarePaginator
{
//配列を1ページに表示する件数分分割する
$displayData = array_chunk($this->itemRepositoryInterface->getItemCollection()->toArray(),
self::DISPLAY_ITEM_FOR_PAGENATION);

//ページがnullの場合は1を設定
if (is_null($currentPageNo)) {
$currentPageNo = 1;
}

return new LengthAwarePaginator(
$displayData[$currentPageNo-1], //該当ページに表示するデータ
count($this->itemRepositoryInterface->getItemCollection()->toArray()), //全件数
self::DISPLAY_ITEM_FOR_PAGENATION, //1ページに表示する数
$currentPageNo, //現在のページ番号
['path' => $requestUrl] //URLをオプションとして設定
);
}



  • 最後にペジネーション結果の表示はbladeで以下のように実装します。

linksメソッドで結果の残りのページヘのリンクをレンダーしています。


index.blade.php


@if($paginator->total() > 0)
<nav aria-label="ページネーション">
<div class="pagination mx-auto my-4">
{{ $paginator->links() }}
</div>
</nav>
@endif


paginateメソッドを呼び出す場合

Illuminate\Pagination\LengthAwarePaginatorインスタンスを受け取っており、

結果を表す多くのメソッドが提供されています。

結果を取得したらその結果とページリンクをBladeを使って表示できます!


まとめ

初期表示時時に1ページ目が表示されて欲しかったのですが、

初期表示時のページ番号はnullで入ってくるため

nullの場合は無理やり1ページ目としている部分がどうにかできないかなと

思っています。。

リクエストの受け取り方や配列の分割方法も改善できそうなので

何かアドバイスがあればいただきたいです!