1. 게시물의 수정/삭제 처리
게시물 수정/삭제에 대한 처리는 GET 방식으로 게시물을 수정이나 삭제할 수 있는 화면을 보는 것으로 시작
BoardController의 read()를 수정해서 /board/modify에도 적용되도록 수정
@GetMapping({"/read", "/modify"})
public void read(Long bno, PageRequestDTO pageRequestDTO, Model model) {
BoardDTO boardDTO = boardService.readOne(bno);
log.info(boardDTO);
model.addAttribute("dto", boardDTO);
}
templates의 board 폴더에는 modify.html을 추가
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
xmlns:th="http://www.thymeleaf.org"
layout:decorate="~{layout/basic.html}">
<head>
<meta charset="UTF-8">
<title>Board Modify</title>
</head>
<div layout:fragment="content">
<div class="row mt-3">
<div class="col">
<div class="card">
<div class="card-header">
Board Modify
</div>
<div class="card-body">
</div> <!-- end card-body -->
</div> <!-- end card -->
</div> <!-- end col -->
</div> <!-- end row -->
</div>
<form> 태그를 추가하고 'dto'라는 이름으로 전달된 BoardDTO 객체를 출력
📍 <form> 태그에 제목 title, 내용 contents 을 수정할 수 있도록 작성하고 전송할 때 필요한 name 속성을 확인
<div class="card-body">
<form th:action="@{/board/modify}" method="post" id="f1">
<div class="input-group mb-3">
<span class="input-group-text">Bno</span>
<input type="text" class="form-control" name="bno" th:value="${dto.bno}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Title</span>
<input type="text" class="form-control" name="title" th:value="${dto.title}" >
</div>
<div class="input-group mb-3">
<span class="input-group-text">Content</span>
<textarea class="form-control col-sm-5" name="content" rows="5" >[[${dto.content}]]</textarea>
</div>
<div class="input-group mb-3">
<span class="input-group-text">Writer</span>
<input type="text" class="form-control" name="writer" th:value="${dto.writer}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">RegDate</span>
<input type="text" class="form-control" th:value="${#temporals.format(dto.regDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
</div>
<div class="input-group mb-3">
<span class="input-group-text">ModDate</span>
<input type="text" class="form-control" th:value="${#temporals.format(dto.modDate, 'yyyy-MM-dd HH:mm:ss')}" readonly>
</div>
<div class="my-4">
<div class="float-end">
<button type="button" class="btn btn-primary listBtn">List</button>
<button type="button" class="btn btn-secondary modBtn">Modify</button>
<button type="button" class="btn btn-danger removeBtn">Remove</button>
</div>
</div>
</form>
</div> <!-- end card-body -->
/board/modify?bno=310 형태로 수정화면 접근
1) 수정 처리
🚀 실제 수정 작업은 POST 방식으로 처리. 수정 후에는 다시 조회 화면으로 이동해서 수정된 내용을 확인할 수 있도록 구현
🚀 수정 후 조회 화면으로 이동시에 검색했던 조건들이 해당하지 않을 수 있어서, 수정 후에는 검색 조건 없이 단순 조회 화면으로 이동하도록 구현
BoardController에는 POST 방식의 modify()를 구현
@PostMapping("/modify")
public String modify(PageRequestDTO pageRequestDTO,
@Valid BoardDTO boardDTO,
BindingResult bindingResult,
RedirectAttributes redirectAttributes) {
log.info("board POST modify..." + boardDTO);
if (bindingResult.hasErrors()) {
log.info("has errors......");
String link = pageRequestDTO.getLink();
redirectAttributes.addFlashAttribute("errors", bindingResult.getAllErrors());
redirectAttributes.addAttribute("bno", boardDTO.getBno());
return "redirect:/board/modify?" + link;
}
boardService.modify(boardDTO);
redirectAttributes.addFlashAttribute("result", "modified");
redirectAttributes.addAttribute("bno", boardDTO.getBno());
return "redirect:/board/read";
}
✓ modify()에는 문제가 발생할 때 'errors'라는 이름으로 다시 수정 페이지로 이동 할 수 있도록 PageRequestDTO의 getLink()를 통해서 기존의 모든 조건을 붙여서 /board/modify'로 이동하게 구성.
✓ 수정 작업에 이상이 없을 때는 아무런 검색이나 페이징 조건없이 /board/read로 이동
modify.html에 문제가 있을 때는 자바스크립트를 이용해서 처리하도록 구성
<script layout:fragment="script" th:inline="javascript">
const errors = [[${errors}]]
console.log(errors)
let errorMsg = ''
if(errors) {
for (let i = 0; i < errors.length; i++) {
errorMsg += `${errors[i].field}은(는) ${errors[i].code} \n`;
}
history.replaceState({}, null, null)
alert(errorMsg);
}
</script>
자바스크립트로 이벤트 처리하는 부분을 작성
const link = [[${pageRequestDTO.getLink()}]];
const formObj = document.querySelector("#f1");
document.querySelector(".modBtn").addEventListener("click", function(e){
e.preventDefault();
e.stopPropagation();
formObj.action = `/board/modify?${link}`;
formObj.method = 'post';
formObj.submit();
}, false);
✓ 수정 처리를 할 때는 나중에 잘못되는 상황을 대비해서 페이지 / 검색 정보도 같이 쿼리 스트링으로 전달
2) 삭제 처리
🚀 BoardController에서 remove()라는 메서드 구성, 삭제 후에는 목록으로 이동하도록 구성
@PostMapping("/remove")
public String remove(Long bno, RedirectAttributes redirectAttributes) {
log.info("remove()...");
boardService.remove(bno);
redirectAttributes.addFlashAttribute("result", "removed");
return "redirect:/board/list";
}
modify.html에는 자바스크립트를 이용해서 /board/remove를 호출하도록 작성
document.querySelector(".removeBtn").addEventListener("click", function(e){
e.preventDefault();
e.stopPropagation();
formObj.action = `/board/remove`;
formObj.method = 'post';
formObj.submit();
}, false);
✓ 정상적으로 삭제가 이루어질 경우 RedirectAttributes를 통해서 'result' 값이 전달되므로 list.html에서는 모달창으로 삭제 처리된 것을 알 수 있음
목록으로 이동하는 버튼의 이벤트 처리는 페이지/검색 조건을 유지하도록 구성
document.querySelector(".listBtn").addEventListener("click", function(e){
e.preventDefault();
e.stopPropagation();
formObj.reset();
self.location = `board/list?${link}`;
}, false);
[ 내용참고 : IT 학원 강의 ]
'Spring & Spring Boot' 카테고리의 다른 글
[Spring Boot] REST 방식의 댓글 처리 준비 (0) | 2024.05.30 |
---|---|
[Spring Boot] AJax와 JASON · 댓글 기능 구현 준비 (0) | 2024.05.30 |
[Spring Boot] 조회 처리 (0) | 2024.05.25 |
[Spring Boot] 등록 처리 (0) | 2024.05.25 |
[Spring Boot] 컨트롤러와 화면 처리 · 목록 화면 출력 (0) | 2024.05.25 |