각각의 리뷰별로 수정 삭제 버튼이 뜨게 만들기는 성공했다.
삭제는 reviewId 만 넘겨주면 됬기에 쉬웠는데
문제는.. 수정하기... 음 어렵다 어려워..
정렬된 순서의 index를 사용해서 그 review를 수정되도록 하려고 했는데
0번째 인덱스만 제대로 선택되고 나머지들은 알수없는 순서의 리뷰에 수정영역이 생성되는것을 확인했다.
<div id="recent-reviews" th:if="${#lists.size(recentReviews) > 0}" >
<div th:each="review, iterStat : ${recentReviews}" class="review-list">
<div class="row-box">
<h1 th:text="${review.id}"></h1>
<input type="hidden" th:value="${review.id}" id="review-id"/>
<input type="hidden" th:value="${review.isSpoiler()}" id="is-reviews-spoiler"/>
<p th:text="${review.user.nickname}" class="review-writer">
<!-- <span th:if="${iterStat.index < 3}" class="best-icon">BEST</span> -->
</p>
<i class="fa-solid fa-ellipsis-vertical" th:id="'show-modal-' + ${iterStat.index}" th:if="${review.getUser().id} == ${userId}"></i>
<div class="update-modal-container" th:id="'modal-container-' + ${iterStat.index}" th:if="${review.getUser().id} == ${userId}">
<button class="update-review-btn" th:data-index="${iterStat.index}" th:data-review-id="${review.id}">수정</button>
<hr />
<button class="delete-review-btn" th:data-review-id="${review.id}">삭제</button>
</div>
</div>
<p th:text="${review.content}" class="review-comment"></p>
<div class="row-box">
<span th:text="${#temporals.format(review.writeDate, 'yyyy-MM-dd HH:mm')}"></span>
<div>
<button id="recommend-like" class="recommend-btn" th:onclick="'javascript:likeReview(' + ${review.id} + ');'">
<i class="fa-regular fa-thumbs-up"></i> <span th:text="${review.likeCount}"></span>
</button>
<button id="recommend-dislike" class="recommend-btn" th:onclick="'javascript:dislikeReview(' + ${review.id} + ');'">
<i class="fa-regular fa-thumbs-down"></i> <span th:text="${review.dislikeCount}"></span>
</button>
</div>
</div>
</div>
</div>
let reviewId = document.getElementById("review-id");
document.addEventListener("DOMContentLoaded", function() {
function enableEditReview(index) {
console.log( "생성된 텍스트 영역의 index = " + index)
let reviewComment = document.querySelectorAll(".review-comment")[index];
let currentContent = reviewComment.innerText;
let textareaField = document.createElement("textarea");
textareaField.value = currentContent;
textareaField.className = "update-comment-textarea";
reviewComment.replaceWith(textareaField);
// Save 버튼 추가
let saveButton = document.createElement("button");
saveButton.innerText = "저장";
saveButton.className = "save-review-btn";
saveButton.onclick = function() {
saveUpdatedReview(index);
};
textareaField.after(saveButton);
}
function saveUpdatedReview(index) {
let textareaField = document.querySelectorAll(".update-comment-textarea")[index];
console.log("saveUpdateReview의 index = " + index)
if (!textareaField) {
console.error('Textarea element not found.');
return;
}
let updatedContent = textareaField.value;
let reviewId = document.querySelectorAll(".update-review-btn")[index].dataset.reviewId;
console.log("리뷰 id = " + reviewId)
fetch(`/reviews/patch/${reviewId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: updatedContent
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Review content updated successfully:', data);
let reviewComment = document.createElement("p");
reviewComment.className = "review-comment";
reviewComment.innerText = updatedContent;
textareaField.replaceWith(reviewComment);
document.querySelectorAll(".save-review-btn")[index].remove();
})
.catch(error => {
console.error('Error updating review content:', error);
});
}
document.querySelectorAll(".update-review-btn").forEach(function(button, index) {
button.addEventListener("click", function() {
enableEditReview(index);
console.log("선택된 리뷰 index = " + index)
});
});
});
코드를 바꿔가며 한시간정도 개발자도구에서 확인해보니 출력되는 index와 실제 조작되는 index가 달랐다.
뭔가..각각의 리뷰들을 구별할것을 추가해줘야할꺼같아서 고유한 식별자를 추가하였다.
<div id="recent-reviews" th:if="${#lists.size(recentReviews) > 0}">
<div th:each="review, iterStat : ${recentReviews}" class="review-list" th:id="'review-' + ${review.id}">
<div class="row-box">
<h1 th:text="${review.id}"></h1>
<input type="hidden" th:value="${review.id}" class="review-id"/>
<input type="hidden" th:value="${review.isSpoiler()}" class="is-reviews-spoiler"/>
<p th:text="${review.user.nickname}" class="review-writer"></p>
<i class="fa-solid fa-ellipsis-vertical" th:id="'show-modal-' + ${iterStat.index}" th:if="${review.getUser().id} == ${userId}"></i>
<div class="update-modal-container" th:id="'modal-container-' + ${iterStat.index}" th:if="${review.getUser().id} == ${userId}">
<button class="update-review-btn" th:data-index="${iterStat.index}" th:data-review-id="${review.id}">수정</button>
<hr />
<button class="delete-review-btn" th:data-review-id="${review.id}">삭제</button>
</div>
</div>
<p th:text="${review.content}" class="review-comment"></p>
<div class="row-box">
<span th:text="${#temporals.format(review.writeDate, 'yyyy-MM-dd HH:mm')}"></span>
<div>
<button id="recommend-like" class="recommend-btn" th:onclick="'javascript:likeReview(' + ${review.id} + ');'">
<i class="fa-regular fa-thumbs-up"></i> <span th:text="${review.likeCount}"></span>
</button>
<button id="recommend-dislike" class="recommend-btn" th:onclick="'javascript:dislikeReview(' + ${review.id} + ');'">
<i class="fa-regular fa-thumbs-down"></i> <span th:text="${review.dislikeCount}"></span>
</button>
</div>
</div>
</div>
</div>
자바스크립트에서도 해당 식별자를 찾도록 변경
document.addEventListener("DOMContentLoaded", function() {
function enableEditReview(reviewId) {
let reviewElement = document.querySelector("#review-" + reviewId);
let reviewComment = reviewElement.querySelector(".review-comment");
let currentContent = reviewComment.innerText;
let textareaField = document.createElement("textarea");
textareaField.value = currentContent;
textareaField.className = "update-comment-textarea";
reviewComment.replaceWith(textareaField);
// Save 버튼 추가
let saveButton = document.createElement("button");
saveButton.innerText = "저장";
saveButton.className = "save-review-btn";
saveButton.onclick = function() {
saveUpdatedReview(reviewId);
};
textareaField.after(saveButton);
}
function saveUpdatedReview(reviewId) {
let reviewElement = document.querySelector("#review-" + reviewId);
let textareaField = reviewElement.querySelector(".update-comment-textarea");
if (!textareaField) {
console.error('Textarea element not found.');
return;
}
let updatedContent = textareaField.value;
fetch(`/reviews/patch/${reviewId}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
content: updatedContent
})
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
console.log('Review content updated successfully:', data);
let reviewComment = document.createElement("p");
reviewComment.className = "review-comment";
reviewComment.innerText = updatedContent;
textareaField.replaceWith(reviewComment);
reviewElement.querySelector(".save-review-btn").remove();
})
.catch(error => {
console.error('Error updating review content:', error);
});
}
document.querySelectorAll(".update-review-btn").forEach(function(button) {
button.addEventListener("click", function() {
let reviewId = this.dataset.reviewId;
enableEditReview(reviewId);
});
});
});
잘뜨는것을 확인헀다.