[무한댓글 게시판] 7. 댓글 수정 / 삭제
댓글 수정 동영상 시연
접속아이디로 작성된 댓글만 수정과 삭제버튼이 뜨도록 jsp 코드 작성을 하였고,
수정버튼을 누르면 input 창으로 바뀌면서 수정이 가능한 상태로 바뀌는 js를 작성하였다.
다시 댓글 수정을 하고 완료 버튼을 누르면 수정된 댓글이 반영이 된것을 확인할수 있다.
boardDetail.jsp
<div class="comments">
<form action="updateComments" method="post">
<table>
<tr>
<th>댓글 번호</th>
<th>작성자</th>
<th>댓글 내용</th>
<th>등록일</th>
<th>수정</th>
<th>삭제</th>
</tr>
<c:if test="${not empty requestScope.commentsList}">
<c:forEach var="c" items="${requestScope.commentsList}">
<tr>
<td><a>${c.comment_id}</a></td>
<td><a>${c.useremail}</a></td>
<td><span class="comment-content">${c.comment_content}</span>
<input type="text" class="edit-comment" style="display: none;"
value="${c.comment_content}"></td>
<td><a>${c.comment_regdate}</a></td>
<c:if test="${sessionScope.loginUser.useremail == c.useremail}">
<td>
<button data-idx="${c.comment_id}" class="edit-btn">수정</button>
</td>
<td>
<button data-idx="${c.comment_id}" class="delete-btn">삭제</button>
</td>
</c:if>
</tr>
</c:forEach>
</c:if>
<c:if test="${empty requestScope.commentsList}">
<tr>
<th colspan="4">내용물 없음</th>
</tr>
</c:if>
</table>
</form>
</div>
form 태그 안에 table형식으로 데이터를 넘겨주기위한 view(jsp)파일을 board detail 페이지에 작성하였다.
board.js
댓글 수정 버튼 js
// 댓글 수정
document.addEventListener('DOMContentLoaded', function () {
// 모든 수정 버튼에 이벤트 리스너 추가
var editButtons = document.querySelectorAll('.edit-btn');
editButtons.forEach(function (button) {
button.addEventListener('click', function () {
// 부모 행 가져오기
var row = button.closest('tr');
// span 및 input 요소의 표시 전환
var commentContentSpan = row.querySelector('.comment-content');
var editCommentInput = row.querySelector('.edit-comment');
commentContentSpan.style.display = 'none';
editCommentInput.style.display = 'block';
// 버튼 텍스트를 '수정 완료'로 변경
button.textContent = '수정 완료';
// 버튼을 업데이트 버튼으로 식별하기 위해 클래스 변경
button.classList.add('update-btn');
// 업데이트 버튼에 이벤트 리스너 추가
button.addEventListener('click', function () {
// 입력에서 업데이트된 댓글 내용 가져오기
var updatedComment = editCommentInput.value;
// span의 내용 업데이트
commentContentSpan.textContent = updatedComment;
// span 및 input 요소의 표시 전환
commentContentSpan.style.display = 'inline';
editCommentInput.style.display = 'none';
// 버튼 텍스트를 다시 '수정'으로 변경
button.textContent = '수정';
// 'update-btn' 클래스 제거
button.classList.remove('update-btn');
});
});
});
});
댓글 수정 완료 버튼 js
// 댓글 수정
document.addEventListener('DOMContentLoaded', function () {
var editButtons = document.querySelectorAll('.edit-btn');
editButtons.forEach(function (button) {
button.addEventListener('click', function (event) {
event.preventDefault();
var row = button.closest('tr');
var commentContentSpan = row.querySelector('.comment-content');
var editCommentInput = row.querySelector('.edit-comment');
if (button.classList.contains('update-btn')) {
// 현재 버튼이 '수정 완료' 상태일 때
var updatedComment = editCommentInput.value;
commentContentSpan.textContent = updatedComment;
commentContentSpan.style.display = 'inline';
editCommentInput.style.display = 'none';
button.textContent = '수정';
button.classList.remove('update-btn');
// Ajax를 사용하여 수정된 댓글을 서버로 전송
var commentId = button.getAttribute('data-idx');
updateCommentOnServer(commentId, updatedComment);
} else {
// 현재 버튼이 '수정' 상태일 때
commentContentSpan.style.display = 'none';
editCommentInput.style.display = 'block';
button.textContent = '수정 완료';
button.classList.add('update-btn');
}
});
});
function updateCommentOnServer(commentId, updatedComment) {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/board/updateComments', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 수정된 댓글 데이터를 서버로 전송
var formData = 'comment_id=' + commentId + '&comment_content=' + encodeURIComponent(updatedComment);
xhr.send(formData);
}
});
댓글 수정과 수정완료 버튼을 만들어서 각 기능을 하도록 js 코드를 만들었다.
그리고 form태그 안에 데이터를 controller 처리를 위한 updateCommentOnServer 함수를 만들어서 값을 넘겨 주었다.
BoardController.java
// 댓글 수정
@PostMapping("/updateComments")
@ResponseBody
public String updateComments(@RequestParam("comment_id") int commentId,
@RequestParam("comment_content") String updatedContent,
HttpSession session, Model model) {
try {
// 댓글 엔티티를 불러와서 수정 메서드 호출
Comments comment = commentsService.selectDetail(commentId); // findById 메서드는 댓글 ID로 댓글을 찾는 메서드로 가정합니다.
if (comment != null) {
comment.setComment_content(updatedContent);
comment.setComment_moddate(
LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
commentsService.save(comment); // 댓글을 저장하는 메서드로 가정합니다.
return "Success";
} else {
return "Fail"; // 댓글을 찾을 수 없는 경우
}
} catch (Exception e) {
e.printStackTrace();
model.addAttribute("error", "댓글 업데이트에 실패했습니다.");
return "Error"; // 예외 발생 시
}
}
데이터를 서버에 담기위한 처리로 controller에 메서드를 만들어주었다.
RequestParam으로 변수들을 받아서 service에 save로 업데이트된 댓글을 저장해주었다.
💡트러블 슈팅
댓글을 수정을 하고 수정이 클라이언트 서버상에서는 수정된 댓글이 반영이 잘되었지만, DB에 수정된 데이터가 업데이트 되지 않았다.
js 부분에 updateCommentOnServer 메서드에 경로를 /board/updateCommetns가 아닌 /updateCommetns로 되어있어서 404 오류가 뜨면서 DB에 저장이 안됐었던 것이었다. 수정을 해주었더니 DB에 잘 저장이 되었다.
또 다른 트러블 슈팅은 모든 수정도 잘 되고 DB에 수정된 댓글은 잘 저장이 되는 기능상에 문제가 없는데 console에 404 오류가 뜨는 것이다 알고봤더니 controller 메서드 부분에
js에 값을 넘겨줘야하는데 @ResponseBody 어노테이션을 안적어줘서 생긴 문제였다.
댓글 삭제 동영상 시연
BoardController.java
// 댓글 삭제
@DeleteMapping(value = "/deleteComments")
@ResponseBody
public ResponseEntity<?> deleteComment(@RequestParam("comment_id") int commentId) {
Comments entity = commentsService.selectDetail(commentId);
if (entity != null) {
entity.setComment_deldate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
entity.setComment_delyn("'Y'");
commentsService.save(entity);
}
return ResponseEntity.ok().build();
}
board.js
//댓글 삭제
// 삭제 버튼 클릭 시
document.addEventListener('DOMContentLoaded', function () {
var deleteButtons = document.querySelectorAll('.delete-btn');
deleteButtons.forEach(function (button) {
button.addEventListener('click', function (event) {
event.preventDefault();
handleDeleteButtonClick(button);
});
});
function handleDeleteButtonClick(button) {
var commentId = button.getAttribute('data-idx');
deleteCommentOnServer(commentId);
}
});
function deleteCommentOnServer(commentId) {
var xhr = new XMLHttpRequest();
xhr.open('DELETE', '/board/deleteComments?comment_id=' + commentId, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// 삭제할 댓글의 ID를 서버로 전송
var formData = 'comment_id=' + commentId;
xhr.send(formData);
// 서버 응답 확인
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('댓글이 성공적으로 삭제되었습니다.');
// 삭제 성공 시 적절한 화면 갱신 로직 추가
window.location.reload();
} else {
console.error('댓글 삭제에 실패했습니다.');
}
}
};
}
💡트러블 슈팅
삭제 기능까지 다 구현을 하고 삭제는 기능이되는데, 새로고침을해야지만 화면에 삭제한 댓글이 보이지 않았다.
새로고침을 하지 않고도 바로바로 삭제한 댓글이 화면에서 보이지 않게 구현하고 싶었다.
js코드에 삭제 성공시 reload()함수를 통해서 화면을 재로딩하게 하였다.