I'd like to apply page nations to the page after searching, but I'm in trouble because I don't know how to do it. It's okay to just think, so I'd appreciate it if you could lend me some wisdom orz Usage environment
  • Java11
  • spring boot
  • Thymeleaf
  • vscode
  • postgres

Specifically, what I want to achieve is

  1. Display the top page like the attached image below. At this point, pressing "2" = like a record with an asset ID of 11 to 20, when the page number is pressed, the record list of that page is displayed.
  2. As shown below, the results of searching by "asset type" are displayed. In the image below, the search result that spans up to 2 pages is acquired as a result of searching with "PC" and the 1st page is displayed.
  3. [What I want to achieve] If i press the page number "2" on the page displayed in 2., I want to display the second page of the results searched and obtained by "PC". However, at present, when "2" is pressed, the 11th to 20th records of all the records acquired in the initial display are displayed as shown in the image below.
Corresponding source code
// omitted
<body><header th: insert = "fragments/page_header :: pageHeader"></header><main>                                   Asset registration                         <form th: action = "@ {/ index /}" th: object = "${searchForm}" method = "GET" name = "searchForm">      <!-Asset ID search window->      <label for = "id">Asset ID</label>      <input type = "text" name = "id" th: value = "${id}" />      <!-Category selection window->      <label for = "categoryId">Asset type</label>      <select name = "categoryId">        <option disabled selected value = "">Please select an asset type</option>        <option
              th: each = "category: ${categoryList}"
              th: selected = "${category.categoryId == selected}"
              th: value = "${category.categoryId}"
              th: text = "${category.categoryName}"
            ></option>      </select>      <!-Administrator name search window->      <label for = "adminName">administrator</label>      <input type = "text" name = "adminName" th: value = "${adminName}" />      <!-Search word window->      <label for = "assetName">Asset name</label>      <input type = "text" name = "assetName" th: value = "${assetName}" />      <button type = "submit">Search</button>    </form>    <form method = "post" th: action = "@ {/ asset/csv}" th: object = "${csvForm}">                  <input type = "hidden" name = "id" th: value = "${asset.id}" /><input type = "hidden" name = "categoryId" th: value = "${asset.categoryId}" />        <input type = "hidden" name = "adminName" th: value = "${asset.adminName}" />        <input type = "hidden" name = "assetName" th: value = "${asset.assetName}" />        <input type = "hidden" name = "remarks" th: value = "${asset.remarks}" />                <button type = "submit">CSV</button>    </form>// Display table omitted
    <!-Paging->  <th: block th: if = "${assetPage.totalPages>0}">    <nav aria-label = "Page navigation">    <ul>      <li>                      <span aria-hidden = "true">&lt;&lt;</span>                  </li>      <li th: if = "${assetPage.getNumber ()>1}">                      <span aria-hidden = "true">&lt;</span>                  </li>      <li th: with = "start = 1, end = ${lastPage}" th: each = "pageNumber: ${pageNumbers}">                   </li>      <li th: if = "${assetPage.totalPages>assetPage.getNumber () + 1}">                      <span aria-hidden = "true">&gt;</span>                  </li>      <li>                      <span aria-hidden = "true">&gt;&gt;</span>                  </li>    </ul>    </nav>  </th: block></main></body></html>
// Controller
// Import omitted
@RequestMapping ("/ index")
public class IndexController {
  private AssetService assetService;
  private CategoryService categoryService;
  public static final int PAGESIZE = 10;
  public static final Sort SORT = Sort.by ("id"). ascending ();
   * Initial display and search of the top page, asset list display when the page number is pressed
   * @param page* @param model
   * @return Asset list of requested page
   * /
  @GetMapping (path = {"/", "/ {page: ^ [1-9] [0-9] * $}"})
  public String assetPage (@PathVariable (name = "page") Optional<Integer>page, @ModelAttribute ("searchForm") Optional<SearchForm>f, Model model) {
    int currentPage = page.orElse (1);// Requested page
    if (currentPage == 0) {currentPage = 1;} // For pressing "<" when the first page is displayed
    Pageable pageable = PageRequest.of (currentPage --1, PAGESIZE, SORT);
    Page  assetPage = assetService.findSearchedAndPaginatedPage (f, pageable);
    model.addAttribute ("assetPage", assetPage);
    int totalPages = assetPage.getTotalPages ();// Get last page
    model.addAttribute ("lastPage", totalPages);
    if (totalPages>0) {
      List<Integer>pageNumbers = IntStream.rangeClosed (1, totalPages) .boxed (). Collect (Collectors.toList ());
      model.addAttribute ("pageNumbers", pageNumbers);
    List<Category>categoryList = categoryService.findAllCategories ();
    model.addAttribute ("categoryList", categoryList);
    if (f.get (). getAdminName ()! = null) {model.addAttribute ("adminName", assetService.adminNameShape (f.get (). getAdminName ()));}
    if (f.get (). getAdminName ()! = null) {model.addAttribute ("assetName", assetService.assetNameShape (f.get (). getAssetName ()));}
    model.addAttribute ("id", f.get (). getId ());
    model.addAttribute ("selected", f.get (). getCategoryId ());
    return "index";
  // Omitted below
// Service
// Import omitted

public class AssetService {
    AssetRepository assetRepos;
// omitted

     * Asset record acquisition method at the time of initial display and search of the top page
     * @param f
     * @param pageable
     * @return
     * /
    public Page  findSearchedAndPaginatedPage (Optional<SearchForm>f, Pageable pageable) {
        Integer id = f.get (). getId ();
        Integer categoryId = f.get (). getCategoryId ();
        String adminName = f.get (). getAdminName ();
        String assetName = f.get (). getAssetName ();
        if (id == null) {id = 0;}
        if (categoryId == null) {categoryId = 0;}
        if (adminName == null) {
            adminName = "";
        } else {
            adminName = adminNameShape (f.get (). getAdminName ());
        if (assetName == null) {assetName = "";
        } else {
            assetName = assetNameShape (f.get (). getAssetName ());
        List  assets = assetRepos.findByIdAndCategoryIdAndAdminNameAndAssetName (id, categoryId, adminName, assetName);// Search based on search conditions (blanks are ignored by SQL)
        int pageSize = pageable.getPageSize ();// Number of records to display per page
        int currentPage = pageable.getPageNumber ();// Current page
        int startItem = pageSize * currentPage;// Top record of the currently displayed page
        List  list = null;// Initialize and hold Asset type variable with null
        if (assets.size ()<startItem) {// ???
            list = Collections.emptyList ();// Make the variable list empty and immutable
        } else {
            int toIndex = Math.min (startItem + pageSize, assets.size ());// "Top record of the currently displayed page" + "10" and "total number of records" whichever is smaller is called toIndex To do
            list = assets.subList (startItem, toIndex);// Number of records from "top record of currently displayed page" to toIndex = Number of records I want to display on the requested page
        Page  assetList = new PageImpl  (list, pageable, assets.size ());// Record information that matches the requested page
        return assetList;
    // Omitted below
// Repository
// Import omitted

public interface AssetRepository extends JpaRepository  {
    @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)
    Asset findById (@Param ("id") int id);
    List  findAllByIdInAndDeleteFlagFalseOrderByIdAsc (List<Integer>ids);
    @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)
    List  findByIdAndCategoryIdAndAdminNameAndAssetName (
        @Param ("id") Integer id,
        @Param ("categoryId") Integer categoryId,
        @Param ("adminName") String adminName,
        @Param ("assetName") String assetName);
    // Omitted below
What I tried
  1. As shown below, add onclick = "document.blueForm.submit ();return false;" to the a tag of the page number =>The page information does not jump to the controller, the same situation as just pressing the [Search] button It has become.
  1. I added the value remaining in the search window to th: href as a parameter as shown below, but the controller cannot receive it.

I searched on the net, but regarding pagenation, I could only find how to apply it at the time of initial display, and I did not know how to apply it after searching.

  • Answer # 1

    It depends on what kind of implementation is expected, but in most cases, all the search conditions are put in the session when the search is performed by pressing the first search button, and when the paging link transitions, the search conditions are extracted from the session and re-searched. I think there are many ways to make it.