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:
parent
60cb1d7d49
commit
146c1bb2a9
@ -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";
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -1,12 +1,13 @@
|
||||
msg.id=ID
|
||||
msg.name=Name
|
||||
msg.gender=Gender
|
||||
msg.percent=Percentage
|
||||
welcome.message=Welcome Student !!!
|
||||
msg.AddStudent=Add Student
|
||||
msg.ListStudents=List Students
|
||||
msg.Home=Home
|
||||
msg.ListTeachers=List Teachers
|
||||
msg.courses=Courses
|
||||
msg.skills=Skills
|
||||
msg.id=ID
|
||||
msg.name=Name
|
||||
msg.gender=Gender
|
||||
msg.percent=Percentage
|
||||
welcome.message=Welcome Student !!!
|
||||
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
|
@ -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>
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user