Fippiyのプログラム学習内容アウトプットBlog

日々の学習内容をアウトプットして振り返りを実施する。

Laravel開発、ページネーション機能をつける【1】indexページのリスト表示にページネーションを実装する

一括登録及び削除機能を搭載しましたが、現状のままでは登録内容が縦に長々と表示されてしまいます。

そこで一定の上限を超えるデータについては次のページで表示出来るようにページネーション機能を実装することにしました。

今回の目的

1ページ内でのリスト表示に上限を設け、データが続く場合はページを変更することで表示できるようにする

なぜやるか

上限のないまま登録を続けると、一つのページで全件表示することとなり、ページ表示処理だけで大量のデータを受け取る必要が出てくるため対策を行う

やりたいこと

  • コントローラーで表示上限までのデータを取得する
  • 複数ページに跨がる場合は、次のページへのリンクを表示させる

やったこと

  • 1ページに対する表示件数を設定する
  • 次ページへのリンクを表示させる

実施内容

ページネーション導入方法を確認する

どう実装するか 

まずは実装方法を調べてみました。以下のサイトを参考にさせて頂きました、ありがとうございます。

readouble.com

qiita.com

laraweb.net

調べてみた結果、paginationを利用して、1ページ内の表示上限を設定するだけで良さそうです。

 

現状設定の確認

書籍情報のリスト表示はindexページで表示しています。

#  ~app/Http/Controllers/BookController.php

public function index(){
 $books = Bookdata::all();
 return view('book.index', ['books' => $books]);
}

現状のindexコントローラーです。

Bookdataに登録されている全件を取得してビュー表示します。

f:id:Fippiy:20190528110249p:plain

index画面表示

今までは1件のみ登録を順番にしており、件数も限られていました。

しかし、一括登録機能などの追加もあり、このまま放置しているとページを表示する度に何万件とかデータが存在すると表示に時間がかかり大量のデータを受け取ることになります。そして、仮に全データを受け取ったとしても全件の内容を人が見ることは…現実的にありえません。

そこで、今回の目的となる1ページに対しての表示上限を設けておき、上限を超える分は次のページ…として表示させます。

 

ページネーションを導入する

ページ上限設定をする

1ページに表示するデータ上限を設定します。

paginateを利用して1ページ表示上限を設定します。たとえば、3件のデータを表示させる場合なら

$books = Bookdata::paginate(3);

これだけ。これで1ページ目に3件のデータが表示できます。

f:id:Fippiy:20190528110625p:plain

ページネーション設定後

設定した通り3件のみ表示されました。

しかし、これでは本当に3件だけ表示されただけなので、次のページを表示させて続きのデータを確認したいです。

f:id:Fippiy:20190528154001p:plain

ページリンク

検索ページなんかによくある、こんな感じのページ表示です。1ページ目を表示中で次のページのリンクをクリックすると続きの結果が見えるようにしたいのです。

 

ページリンクを設定する

そこで、ページネーション用のリンク設定をビューで追加します。 

# ~/resources/views/components/books_list.blade.php

<div class="book-table">
 @if (isset($books))
  @if ($page_path == 'book')
   <form action="{{ route('book.some_delete') }}" method="post">
  @else
   <form action="{{ route('property.some_delete') }}" method="post">
  @endif
  <div class="book-table__btn">
   <span>操作:</span>
   <input type="submit" class="book-table__btn--delete" value="書籍情報一括削除">
   {{ $books->links() }}
  </div>
  {{ csrf_field() }}

ビュー内にリンクを表示するためのコードを追加しました。

$booksにページネーション指定したデータが入っているので、データに対してリンク情報を取り出すことでページネーションとしてのリンク情報が表示できます。

f:id:Fippiy:20190528111351p:plain

ページネーションリンク

スタイル設定がまだできていない状態ですが、リンクとしては表示されました。

< 1 2 3 4 5 > といった具合に次のページと任意のページ番号が表示されています。

 

この表示を出力されているHTMLで確認してみました。

# HTML

<ul class="pagination" role="navigation">
 <li class="page-item disabled" aria-disabled="true" aria-label="« 前へ">
  <span class="page-link" aria-hidden="true">‹</span>
 </li>
 <li class="page-item active" aria-current="page">

  <span class="page-link">1</span>

 </li>
 <li class="page-item">

  <a class="page-link" href="http://127.0.0.1:8000/book?page=2">2</a>

 </li>

 〜 略 〜
</ul>

現在表示しているページは初期表示画面、1ページ目です。

前のページを表示する"<"についてはページがないので"disabled"クラスが指定され、リンクは設定されていません。

現在ページである1ページ目が"active"クラスとなっています。

2ページ目以降については、リンクが設定されており、クリックすることで対応したページが表示されます。

 

リンクのスタイルは実は簡単に設定できる

ビュー表示ページネーションのクラスはbootstrapに対応しているので、bootstrapを導入していれば、スタイルまで完成した状態となります。

f:id:Fippiy:20190528112046p:plain

bootstrapによるスタイル適用

CDNによるスタイルシートを適用すると、リンクが綺麗な状態となりました。

しかし、今回のサイトではbootstrapは導入していません。

むしろ、後から導入すると既存のスタイルシートと競合して形が崩れてしまいました。

f:id:Fippiy:20190528112322p:plain

bootstrap適用全画面
個別にスタイルを設定する

ページネーションの表示についてはスタイルシートを変数して個別に作成しました。

# ~/public/scss/book-index.scss

.pagination {
 display: flex;
 justify-content: center;
 margin: 20px;
 .page-item {
  border: 0.5px solid #eeeeee;
  padding: 15px;
 }
 .disabled {
  color: #222222;
 }
 .active {
  background: #7dc7ea;
 }
 .page-link {
  color: #999999;
 }
}

HTML表示にて確認したクラス名を利用してスタイル設定を実施しました。

 

f:id:Fippiy:20190528114623p:plain

ページネーション表示調整

実際には1ページに表示する件数を増やした上で実装しますが、あくまで今はテスト用にページ表示上限を少なくして表示チェックしています。

ページの上下どちらでもページ遷移出来るように両方つけてみました。

 

以上でページネーション機能としては動作するものができました。

しかし、リスト表示一覧はコンポーネントとして作成しており他のページでも使用しています。

ページ表示をコンポーネント外に出せば問題なく動作しますが、せっかくなので検索ページにもつけて使えるようにしていきたいので、今後実装していきます。