이 내용은 스프링 부트 쇼핑몰 프로젝트 with JPA 책을 학습한 내용입니다.
1. 상품 목록 페이지 결과 화면
상품 목록 테이블 부분, 하단 페이지 부분, 검색 조건 부분 존재
2. 상품 목록 페이지 View
"검색" 버튼을 클릭하면 조회할 페이지 번호를 다시 "0"으로 설정해서 조회해야함
페이지 번호를 전달 받아 form에 설정된 검색 조건 값들을 초기화하여 QueryString으로 보내는 page() 함수
<!-- 사용자 스트립트 추가 -->
<th:block layout:fragment="script">
<script th:inline="javascript">
$(document).ready(function(){
// 검색 버튼이 눌리면
$("#searchBtn").on("click",function(e) {
// form 태그의 전송을 막음 (페이지 번호가 그대로 넘어갈 수 있음)
e.preventDefault();
page(0); <!-- 페이지 0번으로 세팅 -->
});
});
function page(page){
var searchDateType = $("#searchDateType").val();
var searchSellStatus = $("#searchSellStatus").val();
var searchBy = $("#searchBy").val();
var searchQuery = $("#searchQuery").val();
location.href="/admin/items/" + page + "?searchDateType=" + searchDateType
+ "&searchSellStatus=" + searchSellStatus
+ "&searchBy=" + searchBy
+ "&searchQuery=" + searchQuery;
}
</script>
</th:block>
상품 목록 테이블 부분
${items} 변수는 Controller 에서 전달 받은 Page 객체
.getContent() 메소드를 이용하여 Page 객체의 content 부분을 추출
<form th:action="@{'/admin/items/' + ${items.number}}" role="form" method="get" th:object="${items}">
<table class="table">
<thead>
<tr>
<td>상품아이디</td>
<td>상품명</td>
<td>상태</td>
<td>등록자</td>
<td>등록일</td>
</tr>
</thead>
<tbody>
<tr th:each="item, status: ${items.getContent()}">
<td th:text="${item.id}"></td>
<td>
<a th:href="'/admin/item/'+${item.id}" th:text="${item.itemNm}"></a>
</td>
<!-- 아래 문장에서 품절, 판매중이 정확하게 나오지 않는 경우엔 밑에 문장으로 변경하기 -->
<!--<td th:text="${item.itemSellStatus == 0} ? '품절' : '판매중'"></td>-->
<td th:text="${item.itemSellStatus == T(kr.spring.item.constant.ItemSellStatus).SELL} ? '판매중' : '품절'"></td>
<td th:text="${item.createdBy}"></td>
<td th:text="${item.regTime}"></td>
</tr>
</tbody>
</table>
하단 페이지 부분
페이지 객체의 페이지 index 는 0부터 시작, 페이지 표시 번호는 1부터 시작
th:with 을 통해서 변수값을 정의start (페이지 시작 번호) : ((현재 페이지번호 / 보여줄 페이지 수) * 보여줄 페이지수) + 1end (페이지 끝 번호) : start + (보여줄 페이지 수 - 1)페이지의 총 개수가 0개면 end = 1, start + (보여줄 페이지 수 - 1) 보다 작다면 end = 페이지 총 개수
첫 페이지 또는 마지막 페이지면 class 식별자를 추가(classappend) 하여 disabled 적용
현재 페이지이면 active 클래스 추가
페이지 번호를 클릭하면 위에 존재하는 스크립트의 page() 함수 수행
<!-- 부트 스트랩 사용할 때 재사용 가능 -->
<div th:with="start=${(items.number/maxPage)*maxPage + 1}, end=(${(items.totalPages == 0) ? 1 : (start + (maxPage - 1) < items.totalPages ? start + (maxPage - 1) : items.totalPages)})" >
<ul class="pagination justify-content-center">
<li class="page-item" th:classappend="${items.first}?'disabled'">
<a th:onclick="'javascript:page(' + ${items.number - 1} + ')'" aria-label='Previous' class="page-link">
<span aria-hidden='true'>Previous</span>
</a>
</li>
<li class="page-item" th:each="page: ${#numbers.sequence(start, end)}" th:classappend="${items.number eq page-1}?'active':''">
<a th:onclick="'javascript:page(' + ${page - 1} + ')'" th:inline="text" class="page-link">[[${page}]]</a>
</li>
<li class="page-item" th:classappend="${items.last}?'disabled'">
<a th:onclick="'javascript:page(' + ${items.number + 1} + ')'" aria-label='Next' class="page-link">
<span aria-hidden='true'>Next</span>
</a>
</li>
</ul>
</div>
검색 조건 부분
${itemSearchDto} 객체와 매핑
<div class="form-inline justify-content-center" th:object="${itemSearchDto}">
<select th:field="*{searchDateType}" class="form-control" style="width:auto;">
<option value="all">전체기간</option>
<option value="1d">1일</option>
<option value="1w">1주</option>
<option value="1m">1개월</option>
<option value="6m">6개월</option>
</select>
<select th:field="*{searchSellStatus}" class="form-control" style="width:auto;">
<option value="">판매상태(전체)</option>
<option value="SELL">판매</option>
<option value="SOLD_OUT">품절</option>
</select>
<select th:field="*{searchBy}" class="form-control" style="width:auto;">
<option value="itemNm">상품명</option>
<option value="createdBy">등록자</option>
</select>
<input th:field="*{searchQuery}" type="text" class="form-control" placeholder="검색어를 입력해주세요">
<button id="searchBtn" type="submit" class="btn btn-primary">검색</button>
</div>
3. 검색 조건 적용 결과화면