BAEL-1793 Spring with Thymeleaf Pagination for a List (#4290)

* BAEL-1793 Spring with Thymeleaf Pagination for a List

* Replace tabs with 4 spaces in HTML based on editor's feedback.
This commit is contained in:
mmchsusan 2018-05-26 08:16:54 -04:00 committed by KevinGilmore
parent 60cb1d7d49
commit 146c1bb2a9
7 changed files with 239 additions and 11 deletions

View File

@ -0,0 +1,48 @@
package com.baeldung.thymeleaf.controller;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import com.baeldung.thymeleaf.model.Book;
import com.baeldung.thymeleaf.model.Page;
import com.baeldung.thymeleaf.utils.BookUtils;
@Controller
public class BookController {
private static int currentPage = 1;
private static int pageSize = 5;
@RequestMapping(value = "/listBooks", method = RequestMethod.GET)
public String listBooks(Model model, @RequestParam("page") Optional<Integer> page, @RequestParam("size") Optional<Integer> size) {
page.ifPresent(p -> currentPage = p);
size.ifPresent(s -> pageSize = s);
List<Book> books = BookUtils.buildBooks();
Page<Book> bookPage = new Page<Book>(books, pageSize, currentPage);
model.addAttribute("books", bookPage.getList());
model.addAttribute("selectedPage", bookPage.getCurrentPage());
model.addAttribute("pageSize", pageSize);
int totalPages = bookPage.getTotalPages();
model.addAttribute("totalPages", totalPages);
if (totalPages > 1) {
List<Integer> pageNumbers = IntStream.rangeClosed(1, totalPages)
.boxed()
.collect(Collectors.toList());
model.addAttribute("pageNumbers", pageNumbers);
}
return "listBooks.html";
}
}

View File

@ -0,0 +1,29 @@
package com.baeldung.thymeleaf.model;
public class Book {
private int id;
private String name;
public Book(int id, String name) {
super();
this.id = id;
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View File

@ -0,0 +1,61 @@
package com.baeldung.thymeleaf.model;
import java.util.Collections;
import java.util.List;
public class Page<T> {
private List<T> list;
private int pageSize = 0;
private int currentPage = 0;
private int totalPages = 0;
public Page(List<T> list, int pageSize, int currentPage) {
if (list.isEmpty()) {
this.list = list;
}
if (pageSize <= 0 || pageSize > list.size() || currentPage <= 0) {
throw new IllegalArgumentException("invalid page size or current page!");
}
this.pageSize = pageSize;
this.currentPage = currentPage;
if (list.size() % pageSize == 0) {
this.totalPages = list.size() / pageSize;
} else {
this.totalPages = list.size() / pageSize + 1;
}
int startItem = (currentPage - 1) * pageSize;
if (list.size() < startItem) {
this.list = Collections.emptyList();
}
int toIndex = Math.min(startItem + pageSize, list.size());
this.list = list.subList(startItem, toIndex);
}
public List<T> getList() {
return list;
}
public int getPageSize() {
return pageSize;
}
public int getCurrentPage() {
return currentPage;
}
public int getTotalPages() {
return totalPages;
}
}

View File

@ -0,0 +1,28 @@
package com.baeldung.thymeleaf.utils;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.IntStream;
import com.baeldung.thymeleaf.model.Book;
public class BookUtils {
private static List<Book> books = new ArrayList<Book>();
private static final int NUM_BOOKS = 30;
private static final int MIN_BOOK_NUM = 1000;
public static List<Book> buildBooks() {
if (books.isEmpty()) {
IntStream.range(0, NUM_BOOKS).forEach(n -> {
books.add(new Book(MIN_BOOK_NUM + n + 1, "Spring in Action"));
});
}
return books;
}
}

View File

@ -7,6 +7,7 @@ msg.AddStudent=Add Student
msg.ListStudents=List Students
msg.Home=Home
msg.ListTeachers=List Teachers
msg.ListBooks=List Books with paging
msg.courses=Courses
msg.skills=Skills
msg.active=Active

View File

@ -21,6 +21,9 @@
<tr>
<td><a th:href="@{/listTeachers}" th:text="#{msg.ListTeachers}" /></td>
</tr>
<tr>
<td><a th:href="@{/listBooks}" th:text="#{msg.ListBooks}" /></td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,58 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<style>
.pagination {
display: inline-block;
}
.pagination a {
color: black;
float: left;
padding: 5px 5px;
text-decoration: none;
}
.pagination a.active {
background-color: gray;
color: white;
border-radius: 2px;
}
</style>
<head>
<title>Book List</title>
</head>
<body>
<h1>Book List</h1>
<table border="1">
<thead>
<tr>
<th th:text="#{msg.id}" />
<th th:text="#{msg.name}" />
</tr>
</thead>
<tbody>
<tr th:each="book, iStat : ${books}"
th:style="${iStat.odd}? 'font-weight: bold;'"
th:alt-title="${iStat.even}? 'even' : 'odd'">
<td th:text="${book.id}" />
<td th:text="${book.name}" />
</tr>
</tbody>
</table>
<div th:if="${totalPages > 1}" class="pagination"
th:each="pageNumber : ${pageNumbers}">
<a th:href="@{/listBooks(size=${pageSize}, page=${pageNumber})}"
th:text=${pageNumber}
th:class="${pageNumber==selectedPage} ? active"></a>
</div>
<div>
<p>
<a th:href="@{/}" th:text="#{msg.Home}"></a>
</p>
</div>
</body>
</html>