- 부모창에서 자식창 띄우기
- 자식창에서 검색, 페이지네이션 구현
- 자식창의 선택한 데이터를 부모창으로 전달해 부모창에서 데이터 출력
<button type="button" class="popup_btn">상품 선택</button>
//팝업 창을 띄우는 함수
$('#popupBtn').click(function() {
window.open("/shop/products/search", "_blank", "width=600px,height=450px");
});
popup_btn
을 클릭하면 팝업창을 띄우는 함수가 실행됩니다./shop/products/search
GET 방식으로 요청했습니다._blank
속성을 지정하였습니다. 기본값이므로 생략 가능합니다.width=600px, height=400px
으로 지정하였습니다.yarn 입력, 1개씩 보기 선택 후 검색을 해보겠습니다.
@Getter
@Setter
public class QnaPopupSearchCondition {
private String keyword;
private Integer page;
private Integer limit;
public QnaPopupSearchCondition() {
this.page = 1;
this.limit = 1;
}
}
QnaPopupSearchCondition
객체를 만들었습니다.@GetMapping("/search")
public String searchPopupProducts(@ModelAttribute("condition") QnaPopupSearchCondition condition, Model model) {
if (condition.getKeyword() != null) {
PageRequest pageRequest = PageRequest.of(condition.getPage() - 1, condition.getLimit());
Page<QnaPopupDto> qnaPopupDtos = productService.getPopupProducts(pageRequest, condition.getKeyword());
model.addAttribute("products", qnaPopupDtos);
} else {
model.addAttribute("products", null);
}
return "community/qna/qna_popup";
}
GET 방식으로 구현
하였습니다.public Page<QnaPopupDto> getPopupProducts(Pageable pageable, String keyword) {
return productRepository.findAllPopup(pageable, keyword).map(QnaPopupDto::new);
}
public Page<Product> findAllPopup(Pageable pageable, String keyword) {
List<Product> content = queryFactory
.selectFrom(product)
.leftJoin(product.images, productImage)
.on(product.id.eq(productImage.product.id), productImage.imageType.eq(ImageType.DISPLAY))
.where(keywordLike(keyword))
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch();
JPAQuery<Long> countQuery = queryFactory
.select(product.count())
.from(product)
.where(keywordLike(keyword));
return PageableExecutionUtils.getPage(content, pageable, countQuery::fetchOne);
}
private BooleanExpression keywordLike(String keyword) {
return hasText(keyword) ? product.name.contains(keyword) : null;
}
검색어인 keyword 를 where 조건문에 걸어주고 offset()과 limit()을 통해 페이지네이션을 구현하였습니다.
<div class="pagination" th:if="${products != null and products.totalPages > 0}">
<ul>
<li>
//< 에 해당하는 부분
<a href="./qna_popup.html" th:href="@{/shop/products/search(keyword=${condition.keyword}, limit=${condition.limit})}"
class="prev_first">
<span class="material-symbols-outlined">navigate_before</span>
</a>
</li>
//1,2,3에 해당하는 부분
<li th:each="page : ${#numbers.sequence(1, products.totalPages)}">
<a onclick="location.href='./qna_popup.html'" th:onclick="|location.href='@{/shop/products/search(keyword=${condition.keyword}, page=${page}, limit=${condition.limit})}'|"
class="page" th:classappend="${page == products.number + 1} ? 'active'" th:text="${page}">1
</a>
</li>
//> 에 해당하는 부분
<li>
<a th:href="@{/shop/products/search(keyword=${condition.keyword}, page=${products.totalPages}, limit=${condition.limit})}">
<span class="material-symbols-outlined">navigate_next</span>
</a>
</li>
</ul>
</div>
products.totalPages
는 총 페이지 개수입니다. 현재 총 페이지 개수는 3이므로 ${#numbers.sequence(1, products.totalPages)}
는 1,2,3 값을 생성해서 page에 할당해줍니다.yarn 을 검색해 나오는 결과 중 grey yarn 을 선택해보겠습니다.
<a href="javascript:void(0)" class="btn1"
th:onclick="sendResult([[${product.id}]], [[${product.name}]], [[${product.price}]], [[${product.displayImage}]])">
선택
</a>
//팝업창에서 사용자가 선택한 상품 데이터를 부모창으로 전달
<script th:inline="javascript">
//팝업창에서 사용자가 선택한 상품 데이터를 부모창으로 전달
function sendResult(id, name, price, image) {
window.opener.setProductInfo(id, name, price, image);
window.close();
}
</script>
자식창에서 선택 버튼 클릭 시 sendResult() 함수가 실행됩니다.
sendResult()
함수는 상품id, 상품명, 상품가격, 상품 이미지 파일명 4가지 데이터를 부모창에 전달하면서 setProductInfo()를 호출하고 자식창을 닫아줍니다.
<div class="item_wrap">
<div class="thumbnail">
<a href=""><img id="productImage" class="item_img" src="../../images/img_no.png" alt="상품 이미지"></a>
</div>
<div class="description">
<span id="productName" class="item_name"></span>
<span id="productPrice" class="item_price"></span>
<input type="hidden" id="productId" th:field="*{productId}">
<div class="btn_wrap">
<button type="button" class="popup_btn info">상품 상세 정보</button>
<button type="button" id="popupBtn" class="popup_btn">상품 선택</button>
</div>
</div>
</div>
<script th:inline="javascript">
//팝업창에서 보낸 데이터 채우기
function setProductInfo(id, name, price, image) {
// $('#productId').value(id);
$('#productName').text(name);
$('#productPrice').text(price);
$('#productImage').attr('src', '/productImages/' + image);
$('.popup_btn.info').attr("onclick", "location.href='/shop/products/details/" + id + "'");
$('.popup_btn.info').show();
}
</script>
부모창에 데이터가 채워져야 할 부분에 자식창으로부터 전달받은 id, name, price, image 값을 세팅해주면 됩니다.