検索した後のページでもページネーションを適用させたいのですが、そのやり方がわからず、困っております。考え方だけでも良いので、知恵をお貸しいただけますと幸いですorz
######利用環境
- Java11
- spring boot
- Thymeleaf
- vscode
- postgres
具体的に実現したいこととしては、
- 以下の添付画像のようなトップページを表示する。この時点では、「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"><<</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"><</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">></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">>></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}
試したこと
- 以下のように、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;">
- 以下のように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>
ネットで調べてみたのですが、ページネーションに関しては、初期表示の際の適用の仕方しか見つけられず、検索した後の適用の仕方がわかりませんでした。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/24 11:59