일반적인 스프링 게시판은 @GetMapping 그리고 ModelAttribute로 리스트와 페이징을 처리한다. 그래서 게시글을 검색하거나 목록 페이징를 넘기면 웹페이지가 새로 로딩된다. 하지만 Ajax방식으로 페이징을 처리하면 새 로딩 없이 게시글 목록을 갱신할 수 있다.
View에서 Ajax 넘겨주는 function 작성
우선 Controller에서 게시판 리스트를 처음 출력해주는 부분은 기존과 동일하게 Get방식으로 만든다.
@Autowired
private NoticeService service;
@GetMapping("/notice/list")
public String viewList(Model model,
@SessionAttribute(name = "loginMember", required = false) Member loginMember) {
NoticeParam param = new NoticeParam(1, 10, 0);
int count = service.selectCountNotice();
List<Notice> list = service.selectAllNotice(param);
PageInfo pageInfo = new PageInfo(1, 5, count, 10);
model.addAttribute("list", list);
model.addAttribute("count", count);
model.addAttribute("param", param);
model.addAttribute("pageInfo", pageInfo);
model.addAttribute("loginMember", loginMember);
return "notice/list";
}
하지만 JSP파일에서 페이징 부분에서, 클릭 시 movePage라는 함수를 호출하도록 하고, 해당 함수가 Ajax방식으로 데이터를 송수신하게 설계한다. JS에서 $('#noticearea').replaceWith(result); 부분으로 송수신 성공 시, 기존의 게시글 목록+페이징 부분의 코드를 다른 코드로 교체하게 되어 있다.
<main>
<!-- Hero -->
<section class="">
<div class="container">
<div class="row justify-content-center">
<div class="col-12 col-md-8 text-center">
<h1 class="display-2 mb-3">공지사항</h1>
<c:if test="${loginMember.role == 'ADMIN'}">
<div class="btn mb-2 mr-2 btn-outline-primary">
<a href="${path}/notice/write">
글쓰기
</a>
</div>
</c:if>
<div id="noticearea">
<div id="tablearea">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">제목</th>
<th scope="col">좋아요 수</th>
<th scope="col">검색결과: ${count}</th>
</tr>
</thead>
<tbody>
<c:if test="${empty list}">
<tr>
<td colspan="4">조회된 글이 없습니다.</td>
</tr>
</c:if>
<c:forEach var="item" items="${list}" varStatus="status">
<tr>
<th scope="row">${status.count}</th>
<td>
<div class="d-flex align-items-center">
<a href="${path}/notice/view?nno=${item.nno}">
${item.title}
</a>
</div>
</td>
<td>${item.likeCount}</td>
<td>
<div class="d-flex">
<i class="fas fa-edit mr-3" data-toggle="tooltip" data-placement="top" title="Edit item"></i>
<i class="fas fa-trash text-danger mr-2" data-toggle="tooltip" data-placement="top" title="Delete item"></i>
</div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<div class="page-link" onclick="movePage(${pageInfo.prevPage});"><i class="fas fa-angle-double-left"></i></div>
</li>
<c:forEach begin="${pageInfo.startPage}" end="${pageInfo.endPage}" varStatus="status" step="1">
<c:if test="${status.current != pageInfo.currentPage}">
<li class="page-item">
<div class="page-link" onclick="movePage(${status.current});">${status.current}</div>
</li>
</c:if>
<c:if test="${status.current == pageInfo.currentPage}">
<li class="page-item active">
<div class="page-link">${status.current}</div>
</li>
</c:if>
</c:forEach>
<li class="page-item">
<div class="page-link" onclick="movePage(${pageInfo.nextPage});"><i class="fas fa-angle-double-right"></i></div>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
</section>
</main>
<script type="text/javascript">
function movePage(page){
$.ajax({
type: 'post',
url: '${path}/notice/page',
data:{
page : page
},
dataType: "text"
})
.done((result)=>{
$('#noticearea').replaceWith(result);
})
.fail((jqXHR)=>{
console.log(jqXHR);
})
}
</script>
Controller에서 Ajax 처리
앞서 JS코드에서 type: 'post', url: '${path}/notice/page'로 지정했으므로 @PostMapping("/notice/page")의 함수가 Ajax를 처리한다.
반환하는 notice/alist 가 기존의 게시글+페이징을 교체한다.
@PostMapping("/notice/page")
public String noticepage(Model model, int page) {
NoticeParam param = new NoticeParam();
int count = service.selectCountNotice();
param.setPage(page);
PageInfo pageInfo = new PageInfo(param.getPage(), 5, count, 10);
param.setLimit(pageInfo.getListLimit());
param.setOffset(pageInfo.getStartList() - 1);
List<Notice> list = service.selectAllNotice(param);
model.addAttribute("count", count);
model.addAttribute("list", list);
model.addAttribute("pageInfo", pageInfo);
return "notice/alist";
}
교체해주는 JSP파일 작성
기존의 게시글 코드의 <div id="noticearea">내용만들 담아 줄 JSP파일(notice/alist)을 만든다.
이 파일에서도 <div id="noticearea">라고 id값을 동일하게 맞춰야 계속해서 Ajax로 페이징이 작동하여 또 새 데이터를 받은 게시글 목록으로 교체된다.
<div id="noticearea">
<div id="tablearea">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">제목</th>
<th scope="col">좋아요 수</th>
<th scope="col">검색결과: ${count}</th>
</tr>
</thead>
<tbody>
<c:if test="${empty list}">
<tr>
<td colspan="4">조회된 글이 없습니다.</td>
</tr>
</c:if>
<c:forEach var="item" items="${list}" varStatus="status">
<tr>
<th scope="row">${status.count}</th>
<td>
<div class="d-flex align-items-center">
<a href="${path}/notice/view?nno=${item.nno}">
${item.title}
</a>
</div>
</td>
<td>${item.likeCount}</td>
<td>
<div class="d-flex">
<i class="fas fa-edit mr-3" data-toggle="tooltip" data-placement="top" title="Edit item"></i>
<i class="fas fa-trash text-danger mr-2" data-toggle="tooltip" data-placement="top" title="Delete item"></i>
</div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<div class="page-link" onclick="movePage(${pageInfo.prevPage});"><i class="fas fa-angle-double-left"></i></div>
</li>
<c:forEach begin="${pageInfo.startPage}" end="${pageInfo.endPage}" varStatus="status" step="1">
<c:if test="${status.current != pageInfo.currentPage}">
<li class="page-item">
<div class="page-link" onclick="movePage(${status.current});">${status.current}</div>
</li>
</c:if>
<c:if test="${status.current == pageInfo.currentPage}">
<li class="page-item active">
<div class="page-link">${status.current}</div>
</li>
</c:if>
</c:forEach>
<li class="page-item">
<div class="page-link" onclick="movePage(${pageInfo.nextPage});"><i class="fas fa-angle-double-right"></i></div>
</li>
</ul>
</nav>
</div>
'스프링' 카테고리의 다른 글
[MyBatis] mapper.xml의 parameterType에 인자 2개 넣기 (0) | 2024.04.09 |
---|---|
Spring MVC Project 회원가입 프로세스 (0) | 2024.04.04 |
Spring MVC Project 로그인 프로세스 (1) | 2024.04.03 |
Spring MVC Project의 구조 (0) | 2024.04.02 |
[Spring] 세션(Session) 그리고 로그인 (0) | 2024.03.25 |