[Spring Boot] 18. 웹 페이지에서 댓글 수정하기
- -
18장. 웹 페이지에서 댓글 수정하기
18.1. 댓글 수정의 개요
댓글 수정 페이지는 부트스트랩에서 제공하는 모달 기능을 이용해 만든다. 모달(modal)은 웹 페이지에서 새 창을 띄우는 팝업 창과 달리 같은 웹 페이지 내부에서 상위 레이어를 띄우는 방식으로 사용하는 창이다. 모달 창이 뜨면 기존 창은 비활성화가 되고, 모달 창을 종료해야만 원래 화면으로 돌아갈 수 있다.
18.2. 댓글 수정 뷰 페이지 만들기
18.2.1. 수정 버튼과 모달 추가하기
[수정] 버튼을 댓글 리스트에 나타나는 닉네임 옆에 만들어보자.
src > main > resources > templates > comments > _list.mustache
<div class="card-header">
{{nickname}}
// 수정 버튼을 넣을 위치
</div>
[수정] 버튼을 눌렀을 때 모달 창을 띄운다고 했는데, 이 버튼을 '모달 트리거 버튼'이라고 명칭하겠다. 트리거란 영어로 방아쇠란 뜻으로, 모달 트리거 버튼을 클릭하면 총의 방아쇠를 당길 때 처럼 총알이 날아가듯이 모달이 실행된다는 뜻이다. data-bs-xx 속성은 다음과 같다.
· data-bs-toggle="modal"
- 클릭하면 모달이 나타나고 다시 클릭하면 사라짐(토글 역할)
· data-bs-target="#comment-edit-modal"
- 해당 id(comment-edit-modal)의 모달 실행
<!-- Button trigger modal -->
<button type="button"
class="btn btn-sm btn-outline-primary"
data-bs-toggle="modal"
data-bs-target="#comment-edit-modal">수정</button>
'모달 트리거 버튼' 다음으로 '모달 창'의 부트스트랩 코드도 수정하는데, 여기서 모달의 id는 data-bs-target과 동일하게 수정한다.
<!-- Modal -->
<div class="modal fade" id="comment-edit-modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h1 class="modal-title fs-5"
id="exampleModalLabel">댓글 수정</h1>
<button type="button"
class="btn-close"
data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body">
</div>
</div>
</div>
</div>
18.2.2. 수정 폼 삽입하기
src > main > resources > templates > comments > _list.mustache
<div class="modal-body">
<!-- 댓글 수정 폼 -->
<form>
// 중략
</form>
</div>
1. 닉네임 input 박스와 댓글 본문 textarea 박스의 id를 각각 "edit-comment-xx"로 수정한다.
2. 히든 인풋의 <input> 구문으로 댓글의 id와 부모 게시글의 id를 각각 "edit-comment-xx"로 수정한다.
3. 전송 버튼의 id를 "comment-update-btn"으로 수정한다.
<!-- 댓글 수정 폼 -->
<form>
<!-- 닉네임 입력 -->
<div class="mb-3">
<label class="form-label">닉네임</label>
<input type="text" class="form-control"
id="edit-comment-nickname">
</div>
<!-- 댓글 본문 입력 -->
<div class="mb-3">
<label class="form-label">댓글 내용</label>
<textarea type="text" class="form-control" rows="3"
id="edit-comment-body"></textarea>
</div>
<!-- 히든 인풋 -->
<input type="hidden" id="edit-comment-id"/>
<input type="hidden" id="edit-comment-article-id">
<!-- 전송 버튼 -->
<button type="button" class="btn btn-primary"
id="comment-update-btn">수정 완료
</button>
</form>
18.3. 자바스크립트로 댓글 수정하기
18.3.1. 트리거 데이터 전달하기
댓글을 수정하기 위해서는 이전 댓글 데이터를 가져와야 하므로, [수정] 버튼을 클릭했을 때 수정 폼에 이전 댓글 데이터가 전달될 수 있도록 해보자. 그렇기 위해서는 commentDto에 저장된 데이터를 '모달 트리거 버튼'의 속성값으로 가져와야 한다.
{{#commentDtos}} ... {{/commentDtos}} 머스테치 문법을 이용해 data-bs-xx 속성을 추가하고 각각에 id, nickname, body, articleId를 저장한다. 이처럼 data-로 시작하는 속성을 데이터 속성이라고 한다. 데이터 속성은 HTML 요소에 추가 정보를 저장하고 싶을 때 사용한다.
{{#commentDtos}}
<div class="card m-2" id="comments-{{id}}">
<div class="card-header"> <!-- 댓글 헤더 영역 설정 -->
{{nickname}} <!-- 닉네임 보여주기 -->
<!-- Button trigger modal -->
<button type="button"
class="btn btn-sm btn-outline-primary"
data-bs-toggle="modal"
data-bs-target="#comment-edit-modal"
// 추가
data-bs-id="{{id}}"
data-bs-nickname="{{nickname}}"
data-bs-body="{{body}}"
data-bs-article-id="{{articleId}}">수정
</button>
</div>
<div class="card-body"> <!-- 댓글 본문 영역 설정 -->
{{body}} <!-- 본문 보여주기 -->
</div>
</div>
{{/commentDtos}}
받아 온 데이터를 모달의 각 폼에 출력해보자. 이를 모달 이벤트 처리라고 한다. 모달 이벤트 처리를 할려면 먼저 모달을 선택해야 한다. 앞서 사용한 querySelector() 메서드로 모달(comment-edit-modal)을 선택하고 commentEditModal 변수에 저장한다.
모달을 변수화한 후에는 모달이 열리는 이벤트를 감지하고 있다가 이벤트가 발생하면 기존 댓글을 받아와야 한다. 이벤트를 감지하기 위해서는 addEventListener() 메서드를 사용한다. show.bs.modal은 모달 동작의 이벤트 타입이다. function(event)는 모달이 열리는 이벤트를 매개변수로 받아 실행되는 함수로, 이벤트 핸들러(event handler)라고 한다.
이벤트 타입 | 설명 |
show.bs.modal | 모달이 표시되기 직전 실행되는 이벤트 |
shown.bs.modal | 모달이 표시된 후 실행되는 이벤트 |
hide.bs.modal | 모달이 숨겨지기 직전 실행되는 이벤트 |
hidden.bs.modal | 모달이 숨겨진 후 실행되는 이벤트 |
모달 트리거 버튼은 매개변수로 받은 event의 realtedTarget 즉, event.relatedTarget으로 선택하고, 이벤트의 주체 event.target으로 모달을 선택한다.
앞서 데이터 속성을 통해 모달 트리거 버튼의 속성 값으로 댓글의 id, nickname, body, articleId를 저장했는데, 이 값들을 triggerBtn 변수를 통해 가져온다.
가져온 데이터는 모달의 각 폼에 반영하는데, 이때 querySelector("#id") 메서드와 value 속성을 통해 데이터를 저장한다. 예를 들어 닉네임 입력 폼의 id는 "edit-comment-nickname"이므로 querySelector("#edit-comment-nickname").value에 저장한다.
<script>
{
// 모달 요소 선택
const commentEditModal = document.querySelector('#comment-edit-modal');
// 모달 이벤트 감지
commentEditModal.addEventListener("show.bs.modal", function (event) {
// 1. 트리거 버튼 선택
const triggerBtn = event.relatedTarget;
// 2. 데이터 가져오기
const id = triggerBtn.getAttribute("data-bs-id");
const nickname = triggerBtn.getAttribute("data-bs-nickname");
const body = triggerBtn.getAttribute("data-bs-body");
const articleId = triggerBtn.getAttribute("data-bs-article-id");
// 3. 수정 폼에 데이터 반영
document.querySelector("#edit-comment-nickname").value = nickname;
document.querySelector("#edit-comment-body").value = body;
document.querySelector("#edit-comment-id").value = id;
document.querySelector("#edit-comment-article-id").value = articleId;
});
}
</script>
18.3.2. 자바스크립트 REST API 호출하고 응답 처리하기
이제 [수정 완료] 버튼을 클릭해 REST API를 호출해보자. querySelector("#comment-edit-btn")을 선택해 commentUpdateBtn 변수를 가져온다. 클릭 이벤트 감지를 addEventListener() 메서드를 작성한다. 수정 댓글 객체는 객체 리터럴 방식으로 객체의 키(key)인 id, nickname, body, articleId를 querySelector.value 속성으로 각 요소를 선택 후 키 값을 가져온다.
fetch() 함수를 작성할 때 첫 번째 전달값으로 API 주소를 가지고 있는 URL을 넘기고, 두 번째 전달값으로 요청 메서드, 헤더 정보, 전송 본문을 넘긴다. 헤더 정보는 본문 데이터 타입이 JSON임을 명시하는 내용이, 전송 데이터는 comment 객체를 JSON 형태로 변환해 전송하기 위해 JSON.stringfy() 메서드를 사용한다.
// 수정 완료 버튼 선택
const commentUpdateBtn = document.querySelector('#comment-update-btn');
// 클릭 이벤트 처리
commentUpdateBtn.addEventListener("click", function () {
// 수정 댓글 객체 생성
const comment = {
id: document.querySelector("#edit-comment-id").value,
nickname: document.querySelector("#edit-comment-nickname").value,
body: document.querySelector("#edit-comment-body").value,
articleId: document.querySelector("#edit-comment-article-id").value
};
// 객체 생성 확인
console.log(comment);
// 수정 REST API 호출
const url = "/api/comments/" + comment.id;
fetch(url, {
method: "PATCH", // PATCH 요청
headers: { // 전송 데이터 타입 정보(JSON)
"Content-Type": "application/json",
},
body: JSON.stringify(comment) // comment 객체를 JSON 문자열로 변환
}).then(response => {
// HTTP 응답 코드에 따른 메시지 출력
const msg = (response.ok) ? "댓글이 수정됐습니다." : "댓글 수정 실패..!";
alert(msg);
// 현재 페이지 새로고침
window.location.reload();
})
});
'BackEnd > 스프링부트3 백엔드 개발 입문' 카테고리의 다른 글
[Spring Boot] 19. 웹 페이지에서 댓글 삭제하기 (0) | 2024.02.02 |
---|---|
[Spring Boot] 17. 웹 페이지에서 댓글 등록하기 (0) | 2024.01.31 |
[Spring Boot] 16. 웹 페이지에서 댓글 목록 보기 (0) | 2024.01.30 |
[Spring Boot] 15. 댓글 컨트롤러와 서비스 만들기 (2) (0) | 2024.01.29 |
[Spring Boot] 15. 댓글 컨트롤러와 서비스 만들기 (1) (0) | 2024.01.26 |
소중한 공감 감사합니다