【Laravel 入門】ページネーションのつくり方

Laravel

ページネーションとは、データを一定数ごとに取り出し表示する技術です。

下の画像のように、たとえば100件あるデータを10件ずつ取り出し、
リンクで自由にページ移動することができる機能のことですね。



今回は、Laravel でこのページネーションの機能のつくり方をみていきたいと思います。



参考書

ページの表示の作成

まずはコントローラです。

paginate() というメソッド(引数に表示件数)を使用するだけですね。

    //コントローラ
    
    public function index()
    {
      $users = User::paginate(10);
      return view('user.index', compact('users'));
    }


そしてビューは以下のようにします。
(スタイリングに Bootstrap を使用しています)

  <table class="table">
    <tr>
      <th>名前</th>
      <th>メールアドレス</th>
      <th>年齢</th>
    </tr>
    @foreach($users as $user)
    <tr>
      <td>{{ $user->name }}</td>
      <td>{{ $user->email }}</td>
      <td>{{ $user->age }}</td>
    </tr>
    @endforeach
  </table>
  {{ $users->links() }}


以下の部分がページ移動のリンクになります。

  {{ $変数->links() }}



ブラウザの表示↓

ソート順の変更

では続いてソート順の変更を実装します。

以下のように、クリックしたソート項目によって順序が変更されるようにします。

年齢順のソート



では、まずはコントローラです。

    //コントローラ

    public function index(Request $request)
    {
      if($request->sort) {
        $sort = $request->sort;
      }else{
        $sort = 'name';
      }
      
      $users = User::orderBy($sort, 'asc')->paginate(10);
      $users->appends(['sort' => $sort]);
      return view('user.index', compact('users', 'sort'));
    }


$sort という変数に、選択されたソート項目をいれます。
デフォルトでは名前順にしています。

      if($request->sort) {
        $sort = $request->sort;
      }else{
        $sort = 'name';
      }


そして orderBy() メソッドでソートします。
メソッドの呼び出し順ですが、paginate() を常に一番最後に呼び出すようにします。

$users = User::orderBy($sort, 'asc')->paginate(10);


その下の appends() メソッドは、links メソッドが生成するリンクにパラメータを付与します。
これにより、sort=○○ というパラメータをリンクに追加することができます。

$users->appends(['sort' => $sort]);




続いてビューです。

  <div class="text-right text-muted py-4 sort-items">
    <a href="/user?sort=name" class="mx-2">名前</a>/
    <a href="/user?sort=email" class="mx-2">メールアドレス</a>/
    <a href="/user?sort=age" class="mx-2">年齢</a>
  </div>

  <table class="table">
    <tr>
      <th>名前</th>
      <th>メールアドレス</th>
      <th>年齢</th>
    </tr>
    @foreach($users as $user)
    <tr>
      <td>{{ $user->name }}</td>
      <td>{{ $user->email }}</td>
      <td>{{ $user->age }}</td>
    </tr>
    @endforeach
  </table>
  {{ $users->links() }}


a タグのリンクを「/user?sort=○○」として、ソートのパラメータを付与しています。

    <a href="/user?sort=name" class="mx-2">名前</a>/
    <a href="/user?sort=email" class="mx-2">メールアドレス</a>/
    <a href="/user?sort=age" class="mx-2">年齢</a>



また、ページネーションの機能と直接関係ないですが、
ソート項目をクリックしたら太字になるよう JavaScript で調整しています。

const sortItems = document.querySelectorAll('.sort-items a');

switch(@json($sort)) {
  case 'name':
    sortItems[0].classList.add('font-weight-bold', 'text-dark');
    break;

  case 'email':
    sortItems[1].classList.add('font-weight-bold', 'text-dark');
    break;
    
  case 'age':
    sortItems[2].classList.add('font-weight-bold', 'text-dark');
    break;
}

リンクのテンプレートの利用

ページ移動のリンクは今のところ「前へ」「次へ」になっていますが、
links メソッドの引数に使用するテンプレートを指定することで、
これをカスタマイズすることができます。


Laravel がデフォルトで用意しているテンプレートがあるので、以下のコマンドでファイルを追加することができます。

php artisan vendor:publish --tag=laravel-pagination


これによって、「views」のなかに「vendor/pagination」というディレクトリと、その中にテンプレートがいくつか作られます。



たとえば「bootstrap-4.blade.php」を利用するには、links メソッドの引数を以下のように指定します。

{{ $users->links('vendor.pagination.bootstrap-4') }}


これだけで、以下のような表示に変わるかと思います!


もちろんこのテンプレートを自分好みにアレンジすることも可能です。
今回は、「bootstrap-4.blade.php」を以下のように修正しました。

・「最初」と「最後」へ移動するリンクの追加
・現在のページのリンクのみ表示
・データの総数を表示

@if ($paginator->hasPages())
    <nav class="pt-3">
        <ul class="pagination justify-content-center">
            {{-- First Page Link --}}
            <li class="page-item {{ $paginator->onFirstPage() ? 'disabled': '' }}">
                <a class="page-link" href="{{ $paginator->url(1) }}">
                  ‹‹
                </a>
            </li>
            {{-- Previous Page Link --}}
            <li class="page-item {{ $paginator->onFirstPage() ? 'disabled': '' }}">
                <a class="page-link" href="{{ $paginator->previousPageUrl() }}">
                  ‹
                </a>
            </li>

            <li class="page-item active" aria-current="page">
                <span class="page-link">{{ $paginator->currentPage() }}</span>
            </li>

            {{-- Next Page Link --}}
            <li class="page-item {{ $paginator->hasMorePages() ? '': 'disabled' }}">
                <a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">
                  ›
                </a>
            </li>
            {{-- Last Page Link --}}
            <li class="page-item {{ $paginator->hasMorePages() ? '': 'disabled' }}">
                <a class="page-link" href="{{ $paginator->url($paginator->lastPage()) }}" rel="next" aria-label="@lang('pagination.next')">
                  ››
                </a>
            </li>
            <span class="ml-2 align-self-end">/ {{ $paginator->total() }}<span>
        </ul>
    </nav>
@endif


ブラウザの表示↓




今回は以上になります。
ご覧いただきありがとうございました!


参考書

コメント

コンタクトフォーム

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