FireDrago
[js] 페이지네이션 만들기 본문
타임리프를 사용하여 레시피를 받아오는 페이지를 만들어 보자!
페이지네이션은 많은 양의 데이터를 나누어 표시할 때 유용하게 사용된다.

@GetMapping("/all")
public String readAllRecipes(@PageableDefault(size = 2) Pageable pageable,
Model model) {
Page<Recipe> page = recipeService.findAllRecipes(pageable);
List<Recipe> allRecipes = page.getContent();
model.addAttribute("recipes", allRecipes);
model.addAttribute("totalPages", page.getTotalPages());
model.addAttribute("currentPage", page.getNumber() + 1);
return "/recipe/allRecipe";
}
<body>
<div>
<form action="/recipe/search">
<select name="type">
<option value="ingredient">재료명</option>
<option value="recipe">요리명</option>
</select>
<input type="text" name="q" value="검색어를 입력하세요"/>
<button type="submit">검색</button>
</form>
</div>
<a th:each="recipe : ${recipes}" th:href="@{/recipe/{id}(id = ${recipe.id})}">
<img th:src="|/file/${recipe.thumbnail.storedFileName}|" width="300" height="300">
<h2 th:text="${recipe.title}"></h2>
<p th:text="${recipe.instruction}"></p>
</a>
<div id="pagination" th:data-total-pages="${totalPages}" th:data-current-page="${currentPage}"></div>
</body>
th:data-변수명 : Thymeleaf 변수를 통해 전달된 서버 측 데이터를 기반으로 HTML 요소에 맞춤 데이터 속성을 동적으로 설정할 수 있다. 총페이지 수와 현재 페이지를 설정한다.
자바스크립트 이벤트 리스너를 작성한다.
document.addEventListener("DOMContentLoaded", function() {
const totalPages = parseInt(document.getElementById('pagination').dataset.totalPages);
const currentPage = parseInt(document.getElementById('pagination').dataset.currentPage);
generatePagination(totalPages, currentPage);
});
"DomContentLoaded" : Dom (HTML 객체 구조) 가 완성된 후에 실행된다.
아직 img, css 같은 외부 소스가 적용되기 전이다. <==> "load" 는 img, css 모두 적용된 후에 실행된다.
document.getElementById('pagination').dataset.totalPages :
타임리프에서 th:data-... 로 전달한 변수를 dataset 을 사용하여 받아온다.
이벤트 리스너는 Dom 구조가 완성된 후에 변수 파라미터와 함께 generatePagination 메서드를 호출한다.
본격적인 페이지네이션 생성 코드를 만들어보자
function generatePagination(totalPages, currentPage) {
const paginationContainer = document.getElementById('pagination');
paginationContainer.innerHTML = '';
// 첫번째 페이지 생성
paginationContainer.innerHTML += createPageLink(1, currentPage === 1);
if (totalPages > 1) {
// 현재 페이지가 5 이상이면 ... 표시
if (currentPage > 4) {
paginationContainer.innerHTML += createEllipsis();
}
// 2페이지 ~ 마지막 바로앞 페이지 생성
for (let i = Math.max(2, currentPage - 3); i <= Math.min(totalPages - 1, currentPage + 3); i++) {
paginationContainer.innerHTML += createPageLink(i, currentPage === i);
}
// 현재 페이지가 총 페이지 -3 보다 작으면 ... 표시
if (currentPage < totalPages - 3) {
paginationContainer.innerHTML += createEllipsis();
}
// 마지막 페이지 표시
paginationContainer.innerHTML += createPageLink(totalPages, totalPages === currentPage);
}
}
function createPageLink(pageNum, isCurrent = false) {
return `<a href='?page=${pageNum - 1}' class='${isCurrent ? "selected" : ""}'>${pageNum}</a>`
}
function createEllipsis() {
return `<span>...</span>`
}
paginationContainer.innerHTML : HTML 태그를 넣어줄때 호출한다.
+) 자바스크립트에서 '==' : 타입 변경 후 비교 '===' 타입변경 없이 비교한다.
'==' 은 문자열과 정수를 같다고 할 수 있다. '==='를 사용하자
- 첫 번째 페이지는 항상 표시된다. 만약 현재 페이지가 1이라면 createPageLink 메서드에서 class="selected" 속성이 추가된다. CSS로 selected 속성을 스타일링하여 선택된 페이지를 강조한다.
- 현재 페이지가 5 이상이면 첫 페이지 다음에 '...' 표시된다. 현재 페이지와 앞뒤 3페이지만 표시되고 나머지 페이지는 '...'으로 생략된다.
- 반복문을 사용하여 2페이지부터 마지막 바로 앞 페이지까지 표시한다. 이때 2페이지와 현재 페이지 -3에서 시작할지, 마지막 바로 앞 페이지와 현재 페이지 +3에서 끝날지를 판단한다.
- 마지막 페이지를 표시한다. 현재 페이지에 따라 selected 클래스가 추가될 수 있다.
'프로그래밍 > JavaScript' 카테고리의 다른 글
| [jQuery] Ajax 로 JSON 데이터 주고받기 (0) | 2023.07.19 |
|---|---|
| [jQuery] 제이쿼리 Ajax 사용하기 (0) | 2023.07.18 |
| [JavaScript] 회원가입 필수입력 (0) | 2023.06.18 |
| [JavaScript] 장바구니 구현 (0) | 2023.06.15 |
| [JavaScript] 슬라이드 구현하기 (javascript) (0) | 2023.06.13 |
