🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

Q&A

解決済

1回答

2758閲覧

検索結果にもページネーションを適用させたい。

Bonhomme

総合スコア2

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

ページネーション

Webアプリケーションにおいて、1ページに収まらないコンテンツを、各ページへのリンクを並べてアクセスしやすくする手法をページネーションと呼びます。

検索

検索は、あるデータの集まりの中から 目的のデータを見つけ出すことです。

Spring Boot

Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

0グッド

0クリップ

投稿2020/11/23 08:18

編集2020/11/23 08:46

検索した後のページでもページネーションを適用させたいのですが、そのやり方がわからず、困っております。考え方だけでも良いので、知恵をお貸しいただけますと幸いですorz

######利用環境

  • Java11
  • spring boot
  • Thymeleaf
  • vscode
  • postgres

具体的に実現したいこととしては、

  1. 以下の添付画像のようなトップページを表示する。この時点では、「2」押下=資産IDが11~20までのレコードのように、ページ番号を押下すると、そのページのレコード一覧が表示されるようページネーションされている。

トップページ
2. 以下のように、「資産種別」で検索をかけた結果を表示する。以下の画像では、「PC」で検索をかけた結果2ページまでまたがる検索結果が取得され1ページ目が表示されている
イメージ説明
3. 【実現したいこと】 2.で表示したページで、ページ番号「2」を押下したら、「PC」で検索され取得された結果の2ページ目を表示させるようにしたい。しかし、現状、「2」を押下すると、以下の画像のように初期表示で取得した全てのレコードの11から20番目のレコードが表示されてしまう。
イメージ説明

該当のソースコード

HTML

1// 省略 2 3 <body> 4 <header th:insert="fragments/page_header::pageHeader"></header> 5 <main> 6 <div class="container"> 7 <div class="register-box"> 8 <h2 class="register-text"> 9 <a th:href="@{/index/register}" id="register-link">資産登録</a> 10 </h2> 11 </div> 12 <form th:action="@{/index/}" th:object="${searchForm}" method="GET" name="searchForm" id="searchForm"> 13 <!-- 資産ID検索窓 --> 14 <label for="id">資産ID</label> 15 <input type="text" name="id" id="id" th:value="${id}"/> 16 <!-- カテゴリ選択窓 --> 17 <label for="categoryId">資産種別</label> 18 <select name="categoryId" id="categoryId"> 19 <option disabled selected value="">資産種別を選んで下さい</option> 20 <option 21 th:each="category:${categoryList}" 22 th:selected="${category.categoryId == selected}" 23 th:value="${category.categoryId}" 24 th:text="${category.categoryName}" 25 ></option> 26 </select> 27 <!-- 管理者名検索窓 --> 28 <label for="adminName">管理者</label> 29 <input type="text" name="adminName" id="adminName" th:value="${adminName}"/> 30 <!-- 検索ワード窓 --> 31 <label for="assetName">資産名</label> 32 <input type="text" name="assetName" id="assetName" th:value="${assetName}"/> 33 <button id="searchBtn" type="submit">検索</button> 34 </form> 35 <form id="csvform" method="post" th:action="@{/asset/csv}" th:object="${csvForm}"> 36 <div th:each="asset:${assetPage}"> 37 <input type="hidden" name="id" th:value="${asset.id}" /> 38 <input type="hidden" name="categoryId" th:value="${asset.categoryId}" /> 39 <input type="hidden" name="adminName" th:value="${asset.adminName}" /> 40 <input type="hidden" name="assetName" th:value="${asset.assetName}" /> 41 <input type="hidden" name="remarks" th:value="${asset.remarks}" /> 42 </div> 43 <button type="submit">CSV</button> 44 </form> 45// 表示テーブル省略 46 47 <!-- ページング --> 48 <th:block th:if="${assetPage.totalPages > 0}"> 49 <nav aria-label="Page navigation"> 50 <ul class="pagination"> 51 <li class="page-item"> 52 <a th:href="@{/index/}" class="page-link" aria-label="Previous"> 53 <span aria-hidden="true">&lt;&lt;</span> 54 </a> 55 </li> 56 <li class="page-item" th:if="${assetPage.getNumber() > 1}"> 57 <a th:href="@{/index/{page} (page = ${assetPage.getNumber()})}" class="page-link" aria-label="Previous"> 58 <span aria-hidden="true">&lt;</span> 59 </a> 60 </li> 61 <li class="page-item" th:with="start = 1, end = ${lastPage}" th:each="pageNumber : ${pageNumbers}"> 62 <a class="page-link" th:href="@{/index/{page} (page = ${pageNumber})}" th:text="${pageNumber}"></a> 63 </li> 64 <li class="page-item" th:if="${assetPage.totalPages > assetPage.getNumber() + 1 }"> 65 <a th:href="@{/index/{page} (page = ${assetPage.getNumber() + 2})}" class="page-link" aria-label="Next"> 66 <span aria-hidden="true">&gt;</span> 67 </a> 68 </li> 69 <li class="page-item"> 70 <a th:href="@{/index/{page} (page = ${lastPage})}" class="page-link" aria-label="Next"> 71 <span aria-hidden="true">&gt;&gt;</span> 72 </a> 73 </li> 74 </ul> 75 </nav> 76 </th:block> 77 </main> 78 </body> 79</html>

java

1// Controller 2// インポートは省略 3 4@Controller 5@RequestMapping("/index") 6public class IndexController { 7 8 @Autowired 9 private AssetService assetService; 10 11 @Autowired 12 private CategoryService categoryService; 13 14 public static final int PAGESIZE = 10; 15 public static final Sort SORT = Sort.by("id").ascending(); 16 17 /** 18 * トップページの初期表示と検索時、ページ番号押下時の資産リスト表示 19 * @param page 20 * @param model 21 * @return リクエストされたページの資産リスト 22 */ 23 @GetMapping(path = { "/", "/{page:^[1-9][0-9]*$}" }) 24 public String assetPage(@PathVariable(name = "page") Optional<Integer> page, @ModelAttribute("searchForm") Optional<SearchForm> f, Model model) { 25 int currentPage = page.orElse(1); // リクエストされたページ 26 if (currentPage == 0) {currentPage = 1;} // 先頭ページを表示している際の「<」押下用 27 Pageable pageable = PageRequest.of(currentPage - 1, PAGESIZE, SORT); 28 Page<Asset> assetPage = assetService.findSearchedAndPaginatedPage(f, pageable); 29 model.addAttribute("assetPage", assetPage); 30 31 int totalPages = assetPage.getTotalPages(); // 最後ページ取得 32 model.addAttribute("lastPage", totalPages); 33 34 if (totalPages > 0) { 35 List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages).boxed().collect(Collectors.toList()); 36 model.addAttribute("pageNumbers", pageNumbers); 37 } 38 39 List<Category> categoryList = categoryService.findAllCategories(); 40 model.addAttribute("categoryList", categoryList); 41 42 if (f.get().getAdminName() != null) { model.addAttribute("adminName", assetService.adminNameShape(f.get().getAdminName())); } 43 if (f.get().getAdminName() != null) { model.addAttribute("assetName", assetService.assetNameShape(f.get().getAssetName())); } 44 model.addAttribute("id", f.get().getId()); 45 model.addAttribute("selected", f.get().getCategoryId()); 46 47 return "index"; 48 } 49 50 // 以下省略 51} 52

java

1// Service 2// インポート省略 3 4 5 6@Transactional 7@Service 8public class AssetService { 9 10 @Autowired 11 AssetRepository assetRepos; 12// 省略 13 14 15 /** 16 * トップページ初期表示と検索時の資産レコード取得メソッド 17 * @param f 18 * @param pageable 19 * @return 20 */ 21 public Page<Asset> findSearchedAndPaginatedPage(Optional<SearchForm> f, Pageable pageable) { 22 Integer id = f.get().getId(); 23 Integer categoryId = f.get().getCategoryId(); 24 String adminName = f.get().getAdminName(); 25 String assetName = f.get().getAssetName(); 26 if (id == null) { id = 0; } 27 if (categoryId == null) { categoryId = 0; } 28 if (adminName == null) { 29 adminName = ""; 30 } else { 31 adminName = adminNameShape(f.get().getAdminName()); 32 } 33 if (assetName == null) { 34 assetName = ""; 35 } else { 36 assetName = assetNameShape(f.get().getAssetName()); 37 } 38 List<Asset> assets = assetRepos.findByIdAndCategoryIdAndAdminNameAndAssetName(id, categoryId, adminName, assetName); // 検索条件を元に検索(空欄はSQLで無視するようにしてある) 39 40 int pageSize = pageable.getPageSize(); // 1ページあたりの表示するレコード数 41 int currentPage = pageable.getPageNumber(); // 現在のページ 42 int startItem = pageSize * currentPage; // 現在表示しているページの1番上のレコード 43 List<Asset> list = null; // Asset型の変数をnullで初期化して保持 44 if (assets.size() < startItem) { // ??? 45 list = Collections.emptyList(); // 変数listを空のまま不変にする 46 } else { 47 int toIndex = Math.min(startItem + pageSize, assets.size()); // 「現在表示しているページの1番上のレコード」+「10」と「全レコード数」の小さい方をtoIndexとする 48 list = assets.subList(startItem, toIndex); // 「現在表示しているページの1番上のレコード」からtoIndexまでのレコード数 = リクエストされたページで表示したいレコード数 49 } 50 51 Page<Asset> assetList = new PageImpl<Asset>(list, pageable, assets.size()); // リクエストされたページに合致するレコード情報 52 return assetList; 53 } 54 55 // 以下省略 56 57} 58

java

1// Repository 2// インポートは省略 3 4 5public interface AssetRepository extends JpaRepository<Asset, Integer> { 6 7 @Query(value = "SELECT * FROM mst_asset AS a LEFT JOIN mst_category AS c ON a.category_id = c.category_id WHERE a.id = :id", nativeQuery = true) 8 Asset findById(@Param("id") int id); 9 10 List<Asset> findAllByIdInAndDeleteFlagFalseOrderByIdAsc(List<Integer> ids); 11 12 @Query(value = "SELECT * FROM mst_asset WHERE id = CASE WHEN :id = 0 THEN id ELSE :id END AND category_id = CASE WHEN :categoryId = 0 THEN category_id ELSE :categoryId END AND admin_name LIKE concat('%', CASE WHEN :adminName = '' THEN admin_name ELSE :adminName END, '%') AND asset_name LIKE concat('%', CASE WHEN :assetName = '' THEN asset_name ELSE :assetName END, '%') AND delete_flag = false ORDER BY id ASC", nativeQuery = true) 13 List<Asset> findByIdAndCategoryIdAndAdminNameAndAssetName( 14 @Param("id") Integer id, 15 @Param("categoryId")Integer categoryId, 16 @Param("adminName") String adminName, 17 @Param("assetName") String assetName); 18 19 // 以下省略 20 21}

試したこと

  1. 以下のように、onclick="document.blueForm.submit(); return false;"をページ番号のaタグに追記=>ページ情報がコントローラに飛ばず、ただ[検索]ボタンを押下したのと同じ状況になってしまった。

HTML

1<a th:href="@{/index/{page} (page = ${assetPage.getNumber() + 2})}" class="page-link" aria-label="Next" onclick="document.searchForm.submit(); return false;">
  1. 以下のようにth:hrefに検索窓に残っている値をパラメータとして付けたが、コントローラ側で受け取れない

HTML

1<a class="page-link" th:href="@{/index/{page} (page = ${pageNumber}, id = ${id}, categoryId = ${categoryId}, adminName = ${adminName}, assetName = ${assetName})}" th:text="${pageNumber}"></a>

ネットで調べてみたのですが、ページネーションに関しては、初期表示の際の適用の仕方しか見つけられず、検索した後の適用の仕方がわかりませんでした。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

どのような実装を想定しているか次第ですが、大抵は最初の検索ボタン押下での検索時に検索条件全てをセッションに入れておいて、ページングリンク遷移時はセッションから検索条件を取り出して再検索という作り方をすることが多いのではと。

投稿2020/11/23 21:39

m.ts10806

総合スコア80875

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Bonhomme

2020/11/24 11:59

ご回答まことにありがとうございます。 アドバイスをもとに試してみたところ、こちらの問題解決することができました。ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問