Laravel開発、ページネーション機能をつける【2】検索ページのリスト表示にページネーションを実装する
indexページに表示される書籍情報一覧表示に対してのページネーション機能を設定しました。
コンポーネントによるリスト表示に対してページネーション化していますので、同じコンポーネントを利用している検索ページにもページネーション機能を追加することにしました。
今回の目的
リスト表示コンポーネントを利用している検索ページにてページネーションを適用させる
なぜやるか
検索結果が大量にあった場合に、全結果を表示するのではなくページ遷移による個別表示を行うことでユーザーに対して扱いやすい結果表示とするため
やりたいこと
- ページネーション機能を検索結果に対応させる
やったこと
- 検索処理にページネーションを導入する
- 検索時のデータ処理をpostからgetに修正する
- ページネーションリンクを場合分けする
- 検索結果の件数表示をする
実施内容
検索ページを確認する
検索結果が表示されない
検索ページはワード入力+検索によって、結果がリストとして表示されるページです。
検索結果は、この画面の下に一覧表示されます。
ページネーション化コンポーネントと同じ物を使用しているので、ページリンクが付与されて表示されます。
そのため、ページネーション対応したデータを準備する必要が有ります。このまま検索してもエラー画面となり正しく表示はできません。
テストによる確認
書籍情報ページに関連するテストによっても、検索結果を表示できずにエラーとなりました。
[テスト結果]
# ~/tests/Feature/BookdataTest.php
$ vendor/bin/phpunit tests/Feature/BookdataTest.php
PHPUnit 7.5.7 by Sebastian Bergmann and contributors.
.......FF....................... 32 / 32 (100%)
Time: 8.71 seconds, Memory: 32.00 MB
There were 2 failures:
1) Tests\Feature\BookdataTest::test_findTitle_ok_yesMatchFindTitle
Expected status code 200 but received 500.
Failed asserting that false is true.
~/book-property-management/vendor/laravel/framework/src/Illuminate/
Foundation/Testing/TestResponse.php:133
~/book-property-management/tests/Feature/BookdataTest.php:282
2) Tests\Feature\BookdataTest::test_findTitle_ok_noMatchFindTitle
Expected status code 200 but received 500.
Failed asserting that false is true.
~/book-property-management/vendor/laravel/framework/src/Illuminate/
Foundation/Testing/TestResponse.php:133
~/book-property-management/tests/Feature/BookdataTest.php:307
FAILURES!
Tests: 32, Assertions: 321, Failures: 2.
[テストコード]
テスト結果によると282行目と307行目に問題があるように見えます。
実際に282行目を確認すると、検索結果表示に対してのステータスが200であることを確認していますが、先の問題を解決していないため500ステータスとなってしまっている為、不一致となっています。307行目に関しても検索結果表示に関する物です。
ページネーション対応を実施する
検索結果をpagination対応にする
indexページ同様に、paginationを付与して対応させます。
[変更前]
# ~/app/Http/Controllers/BookController.php
検索結果に対してpaginateを付与します。
結果表示に対して2件の上限を設定しました。
この状態で実際に検索を行います。
2件の検索結果が表示されました。
しかし、次のページを表示しようとすると消えてしまいます。
確認の為、ページネーションの表示件数を増やして検索結果を全て表示してみます。
実際には4件のデータがあり正常出力されている状態です。
先程は2件のページネーション指定をしており、ページネーション表示自体はできていたが、検索結果も2件となっていました。こちらも修正がいりそうです。
検索結果ページのページネーション問題を解決する
どう作成するか?
検索ページでのページネーション対応について調べてみました。こちらを参考にさせて頂きました、ありがとうございます。
こちらの情報によると検索結果に対応するURLがページネーションのリンクに設定されていない為にリンクをクリックするとURLが異なる為に表示がきえるようです。
検索ページのURLはこちらです。
~/book/find
検索後は検索ワードを含むURLとなります。
~/book/search?find=検索ワード
URLが対応できていない
ところが、自分のサイトを確認してみたのですが、URLは変わりません。
検索しても"~/book/find"のままです。
検索ページのフォームはこうなっています。
# ~/resources/views/book/find.blade.php
postで作成していました。これではURLに検索結果を反映した状態にはなりません。
getメソッドでないと対応できません。
検索に関してはそもそもDBへデータ保存するわけでもないのでpostにする必要なかったですね…。
というわけで、postからgetに修正する必要がでてきました。
検索メソッドを修正する
まずはフォームを修正します。
# ~/resources/views/book/find.blade.php
メソッドをgetに修正と、アクション名を変更しました。
今までは、getのbook/findに対してpostのbook/findとしてデータ送信していました。
今回、同じgetを利用することとなり名前が重複するので変更しています。
アクション名変更に伴って、ルーティングについても記述を変更しています。
# ~/routes/web.php
これで検索することでURLに検索結果が付与された状態になりました。
しかし、これだけでは次のページへ移動してもデータは消えてしまいます。
ページネーションリンク対応する
ここで改めて表示させるページのURLを確認します。
index一覧表示ページ
- ~/book/index
indexページネーション(2ページ目)
- ~/book?page=2
検索ページトップ
- ~/book/find
検索結果ページ
- ~/book/search?find=検索ワード
検索ページ表示リンク(2ページ目)←問題点
- ~/book/search?page=2
このようになっています、最後の検索後のページに関しては検索ワードが消えてしまっており、これが原因で次のページに移動するとデータが消えてしまいます。
希望するリンクURLはこちらです。
検索結果ページ(2ページ目)
~/book/search?find=検索ワード&page=2
検索したワード結果に対しての2ページ目と標記できれば対応できそうです。
そこでページネーションのリンクにappendsを使用して文字列を付け加えます。
findは検索フォームに使用している名前です。これによって"find=検索ワード"を付与したリンクとして生成できます。
これで検索ページでのURL対応は完了しました、2ページ目、3ページ目と進むと、続きのデータが表示されるようになりました。
結果表示に検索件数を表示させる
ページネーション実装時の確認で上限2件に対して、実際の検索結果は4件となっていました。
ページネーションとしてはこれで問題ないのですが、やはり数値は検索数が表示されるべきです。
しかし、検索数だけの為に検索をもう一度するには非効率です。そこで処理方法を調べてみました。こちらを参考にさせて頂きました、ありがとうございます。
totalを使えば簡単に検索総数がだせそうです。
# ~/app/Http/Controllers/BookController.php
検索件数表示箇所で$books->total()として結果数を参照することで1ページ表示数ではなく、検索結果数を表示させることができました。
以上で書籍情報を扱うページでのリスト表示に対してページネーションによる複数ページを表現することができました。
残るは所有書籍ページへの対応と、ページネーション化に伴うテストの実装をおこなっていきます。