0
votes

I would like to find a complete solution to Thymeleaf pagination using Spring PagingAndSortingRepository DAO. I got a partial solution working, but I can not get the final one. I think it would be interesting for everyone else as a code snipet, so I will ask for the whole thing. I could not find a solution on the web which is kind of strange for me (since I think it could be a quite common problem).

The final solution should behave like Google's pagination: with arrows on both sides only if it makes sense; with a maximun of 10 numbers (for example), and it should move from 1..10 --> 11..20 and so on, when you click the right arrow; and move to 5..15 when you click on 10. Just like google, you know. The size controls the number of items in each page, not the number of blocks or links in the pagination bar.

I have a DAO repository in Spring that extends PagingAndSortingRepository ...

package music.bolo.domain.repository;

import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.stereotype.Repository;

import music.bolo.domain.entity.Announcement;

@Repository public interface AnnouncementDao extends PagingAndSortingRepository {

Announcement findFirstByOrderByDateDesc(); }

So my service can make a request and each page will get the totalPageNumbers (http://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Page.html)...

private final static int PAGESIZE = 2;

.. .. @Autowired annotations...

  public Page<Announcement> readAnnouncementPage (int pageNumber){
          PageRequest request = new PageRequest(pageNumber-1, PAGESIZE, Sort.Direction.DESC, "date");
          return announcementDao.findAll(request);    }

My Controller uses the data to send all the information to Thymeleaf

  @RequestMapping(value = "/viewannouncements", method = RequestMethod.GET)   
  ModelAndView viewAnnouncements(ModelAndView modelAndView, @RequestParam(name = "p", defaultValue = "1") int  pageNumber) {

  Page<Announcement> page =  announcementService.readAnnouncementPage(pageNumber);

  modelAndView.getModel().put("page2th", page);

  modelAndView.setViewName("viewannouncements");

  return modelAndView;    }

My solution is partial, it shows all the pages all the time, no arrow control (actually useless) and without any other funcionality, but it is the most I could make it work without bugs.

	<div class="tag-box tag-box-v7 text-justify">
		 <!-- <h2>Pagination Centered</h2>-->
		<div class="text-center">
			<ul class="pagination">
				<li><a href="#">&laquo;</a></li>
				<!--<li>&laquo;</li>-->
				<li th:each="i : ${#numbers.sequence( 1, page2th.TotalPages)}">
					<a th:href="@{'/viewannouncements?p='}+${ i }" th:text="${ i }">1</a></li>
				<!--<li>&raquo;</li>-->
				<li><a href="#">&raquo;</a></li>
			</ul>
		</div>
	</div>
2
You could add to your view dataTables which support pretty well pagination and is easy to implement - cralfaro
Thanks HitHam, I tried the code from stackoverflow.com/questions/18490820/… but the problem I see there is that it does not implement the Blocks. That is, if you have 100 pages of results (5000 links), you want to show them in 10 blocks (with size of 50 results in each block), and move from block to block, that is not considered. - Mike
Hitham, I could not make it work with the Github exmaple, but it looks like it uses the page size (for the number of items in each page), but not a block size (for the number of pages in each pagination bar). Same problem. - Mike
Thanks Cralfaro, but I would like to find a solution using the paging and sorting object. - Mike

2 Answers

5
votes

This is an example of pagination with SpringBoot and Thymeleaf templates, you can try it.
It is self-explanatory.
Following you can find link to GitHub repo - https://github.com/karelp90/control_asp

see these screenshoots

see these screenshoots

0
votes
<div class="tag-box tag-box-v7 text-justify">
    <div class="text-center">
        <ul class="pagination" th:with="elementsperpage=2, blocksize=10, pages=${page2th.Number}/${elementsperpage}, wholepages=${format.format(pages)},
whole=(${page2th.Number}/${blocksize})+1, wholex=${format.format(whole)}, startnlockpage=${wholepages}*${blocksize+1}, endblockpage=${wholepages}*${blocksize+1}, 
startpage=${wholex-1}*${blocksize}, endpage=(${wholex}*${blocksize})+1">

            <li>
                <a th:if="${startpage gt 0}" th:href="@{${'/viewannouncements?p='}+${startpage}}">&lt;&lt;</a>
                <a th:if="${startpage eq 0}" href="javascript:void(0);">&lt;&lt;</a>
            </li>

            <li th:each="pageNo : ${#numbers.sequence(endpage-11, (endpage lt page2th.TotalPages)? endpage-2 : page2th.TotalPages-1)}" 
            th:class="${page2th.Number eq pageNo}? 'active' : ''">
                    <a th:if="${page2th.Number eq pageNo}" href="javascript:void(0);">
                        <span th:text="${pageNo + 1}"></span>
                    </a>
                    <a th:if="${not (page2th.Number  eq pageNo)}" th:href="@{${'/viewannouncements?p='}+${pageNo+1}}">
                        <span th:text="${pageNo + 1}"></span>
                    </a>
            </li>

            <li>
                <a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" th:href="@{${'/viewannouncements?p='}+${endpage}}">&gt;&gt;</a>
                <a th:if="${(endpage*elementsperpage) le (page2th.TotalElements)}" href="javascript:void(0);"></a>
            </li>



        </ul>
    </div>
</div>