Vous pouvez facilement implémenter la fonctionnalité de pagination d'écran avec Spring Boot + Thymeleaf. Image d'écran une fois terminé
@Entity
@Table(name="word_info")
public class Word implements Serializable {
private static final long serialVersionUID = -870708489937857961L;
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="seqTable")
@TableGenerator(name="seqTable", table="seq_table", pkColumnName="seq_name", pkColumnValue="word_seq", valueColumnName="seq_value")
@Column(name="id")
private Long id;
@Column(name="word")
private String word;
@Column(name="meaning")
private String meaning;
@Column(name="example")
private String example;
//get / set omis
...
}
Définissez une classe de référentiel JPA pour obtenir la liste. Utilisez la classe Page au lieu de List.
@Repository
public interface WordRepository extends CrudRepository<Word, Long>{
public Page<Word> findAll(Pageable pageable);
}
@Service
public class WordService {
@Autowired
private WordRepository wordRepo;
public Page<Word> getAllWord(Pageable pageable) {
return wordRepo.findAll(pageable);
}
}
@Controller
public class MainController {
@Autowired
private WordService wordService;
@RequestMapping(value="/word/wordList", method=RequestMethod.GET)
public String getWordList(Model model, Pageable pageable) {
Page<Word> wordsPage = wordService.getAllWord(pageable);
model.addAttribute("page", wordsPage);
model.addAttribute("words", wordsPage.getContent());
model.addAttribute("url", "/word/wordList");
return "/word/wordList";
}
}
Définissez le nombre maximum d'éléments à afficher pour chaque page.
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
//Nombre d'éléments à afficher par page
resolver.setFallbackPageable(new PageRequest(0, 5));
argumentResolvers.add(resolver);
super.addArgumentResolvers(argumentResolvers);
}
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<link th:substituteby="common/header :: common_header"/>
<title>Word List</title>
</head>
<body>
<table border="1">
<tr>
<th>ID</th>
<th>WORD</th>
<th>MEANING</th>
<th>EXAMPLE</th>
</tr>
<tr th:each="word:${words}">
<td th:text="${word.id}"></td>
<td th:text="${word.word}"></td>
<td th:text="${word.meaning}"></td>
<td th:text="${word.example}"></td>
</tr>
</table>
<div th:fragment='paginationbar'>
<ul>
<li th:class="${page.first} ? 'disabled':''" style="display:inline">
<span th:if="${page.first}">← Premier</span>
<a th:if="${not page.first}" th:href="@{${url}(page=0)}">← Premier</a>
</li>
<li th:each='i : ${#numbers.sequence(0, page.totalPages-1)}' th:class="(${i}==${page.number})? 'active' : ''" style="display:inline">
<span th:if='${i}==${page.number}' th:text='${i+1}'>1</span>
<a th:if='${i}!=${page.number}' th:href="@{${url}(page=${i})}">
<span th:text='${i+1}'>1</span>
</a>
</li>
<li th:class="${page.last} ? 'disabled':''" style="display:inline">
<span th:if="${page.last}">Fin ➝</span>
<a th:if="${not page.last}" th:href="@{${url}(page=(${page.totalPages}-1))}">Fin ➝</a>
</li>
</ul>
</div>
</body>
</html>
Dans le cas d'un grand nombre de pages comme indiqué ci-dessous, si vous souhaitez afficher uniquement certains numéros de page, vous pouvez créer une classe wrapper pour Page et la personnaliser.
public class PageWrapper<T> {
public static final int MAX_PAGE_ITEM_DISPLAY = 5;
private Page<T> page;
private List<PageItem> items;
private int currentNumber;
private String url;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public PageWrapper(Page<T> page, String url){
this.page = page;
this.url = url;
items = new ArrayList<PageItem>();
currentNumber = page.getNumber() + 1;
int start, size;
if (page.getTotalPages() <= MAX_PAGE_ITEM_DISPLAY){
start = 1;
size = page.getTotalPages();
} else {
if (currentNumber <= MAX_PAGE_ITEM_DISPLAY - MAX_PAGE_ITEM_DISPLAY/2){
start = 1;
size = MAX_PAGE_ITEM_DISPLAY;
} else if (currentNumber >= page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY/2){
start = page.getTotalPages() - MAX_PAGE_ITEM_DISPLAY + 1;
size = MAX_PAGE_ITEM_DISPLAY;
} else {
start = currentNumber - MAX_PAGE_ITEM_DISPLAY/2;
size = MAX_PAGE_ITEM_DISPLAY;
}
}
for (int i = 0; i<size; i++){
items.add(new PageItem(start+i, (start+i)==currentNumber));
}
}
public List<PageItem> getItems(){
return items;
}
public int getNumber(){
return currentNumber;
}
public List<T> getContent(){
return page.getContent();
}
public int getSize(){
return page.getSize();
}
public int getTotalPages(){
return page.getTotalPages();
}
public boolean isFirstPage(){
return page.isFirst();
}
public boolean isLastPage(){
return page.isLast();
}
public boolean isHasPreviousPage(){
return page.hasPrevious();
}
public boolean isHasNextPage(){
return page.hasNext();
}
public class PageItem {
private int number;
private boolean current;
public PageItem(int number, boolean current){
this.number = number;
this.current = current;
}
public int getNumber(){
return this.number;
}
public boolean isCurrent(){
return this.current;
}
}
}
Utilisez une classe wrapper au lieu de Page.
@Controller
public class MainController {
@Autowired
private WordService wordService;
@RequestMapping("/word/register")
public String wordRegister(WordForm wordForm) {
wordService.addWord(wordForm);
return "/word/wordRegister";
}
@RequestMapping(value="/word/wordList", method=RequestMethod.GET)
public String getWordList(Model model, Pageable pageable) {
Page<Word> wordPage = wordService.getAllWord(pageable);
PageWrapper<Word> page = new PageWrapper<Word>(wordPage, "/word/wordList");
model.addAttribute("page", page);
model.addAttribute("words", page.getContent());
return "/word/wordList";
}
}
Thymeleaf
Modifiez la partie de pagination comme suit.
...
<div th:fragment='paginationbar'>
<ul class='pagination pagination-centered'>
<li th:class="${page.firstPage}?'disabled':''" style="display:inline">
<span th:if='${page.firstPage}'>← Premier</span>
<a th:if='${not page.firstPage}' th:href='@{${page.url}(page=0,size=${page.size})}'>← Premier</a>
</li>
<li th:class="${page.hasPreviousPage}? '' : 'disabled'" style="display:inline">
<span th:if='${not page.hasPreviousPage}'>«</span>
<a th:if='${page.hasPreviousPage}' th:href='@{${page.url}(page=${page.number-2},size=${page.size})}'>«</a>
</li>
<li th:each='item : ${page.items}' th:class="${item.current}? 'active' : ''" style="display:inline">
<span th:if='${item.current}' th:text='${item.number}'>1</span>
<a th:if='${not item.current}' th:href='@{${page.url}(page=${item.number-1},size=${page.size})}'>
<span th:text='${item.number}'>1</span>
</a>
</li>
<li th:class="${page.hasNextPage}? '' : 'disabled'" style="display:inline">
<span th:if='${not page.hasNextPage}'>»</span>
<a th:if='${page.hasNextPage}' th:href='@{${page.url}(page=${page.number},size=${page.size})}'>»</a>
</li>
<li th:class="${page.lastPage}? 'disabled' : ''" style="display:inline">
<span th:if='${page.lastPage}'>Fin ➝</span>
<a th:if='${not page.lastPage}' th:href='@{${page.url}(page=${page.totalPages - 1},size=${page.size})}'>Fin ➝</a>
</li>
</ul>
</div>
...
Référence: https://github.com/mtiger2k/pageableSpringBootDataJPA
Recommended Posts