프로젝트

가전제품 대여 웹사이트 (세숫대여) - 게시판 댓글 수정/삭제 기능 구현

sejin2 2023. 9. 29. 21:47

게시글 상세보기 하단에 댓글을 작성하고, 작성된 댓글을 조회하는 작업까지 완료했다. 

다음은 댓글을 수정하고, 삭제하는 기능을 구현해야 한다.

먼저 댓글 수정 작업을 시도해본다 !  댓글 수정하기 버튼을 누르면, 수정할 수 있는 폼이 있어야한다. 게시글 수정은 따로 jsp를 만들었지만, 댓글은 상세보기 하단에 있으므로 form 형식으로 만들어준다. 

freeboarddetail.jsp 하단에 edit-reply form 생성

 <tr>
    <td colspan="5">
        <div id="reply-edit-area-${freeBoardReview.freeBoardReplyNo}" style="display: none">
            ${sessionScope.loginuser.memberId} &nbsp;&nbsp; [댓글 수정 시간 : ${freeBoardReview.replyCreateDate}] <br />
            <br />
            <form action="edit-reply" method="post" style="width: 105%; resize: none;">
                <input type="hidden" name="freeBoardReplyNo" value="${freeBoardReview.freeBoardReplyNo}" />
                <input type="hidden" name="freeBoardNo" value="${freeBoard.freeBoardNo}" />
                <input type="hidden" name="pageNo" value="${pageNo}" />
                <textarea name="replyContent" style="width: 70%; resize: none; border-radius: 80px" rows="2" maxlength="200" >${freeBoardReview.replyContent}</textarea>
                <br />
                <div class="btn btn-sm btn-primary">
                    <a class="update-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">수정완료</a>
                </div>
                <div class="btn btn-sm btn-primary">
                    <a class="cancel-edit-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">수정취소</a>
                </div>
            </form>
        </div>
    </td>
</tr>

수정완료 버튼 클릭 이벤트처리 ( JSTL 사용 )

$(".edit-reply").on('click', function(event) {
        const freeBoardReplyNo = $(this).attr("data-reply-no"); 
        
        $('#reply-edit-area-' + freeBoardReplyNo).css('display', '');
        $('#reply-view-area-' + freeBoardReplyNo).css('display', 'none');

        if (currentEditFreeBoardReplyNo) {
            $('#reply-edit-area-' + currentEditFreeBoardReplyNo).css('display', 'none');
            $('#reply-view-area-' + currentEditFreeBoardReplyNo).css('display', '');
        }
        currentEditFreeBoardReplyNo = freeBoardReplyNo; 
    })

 FreeBoardReviewController.java

@PostMapping(path = {"/edit-reply"}) 
	public String editFreeBoardReview(FreeBoardReviewDto freeBoardReview,
									  @RequestParam(defaultValue="-1") int pageNo) {  
		freeBoardReviewService.editFreeBoardReview(freeBoardReview); 
		return String.format("redirect:freeboarddetail?freeBoardNo=%d&pageNo=%d", freeBoardReview.getFreeBoardNo(), pageNo);
	}

FreeBoardReviewService.java

void editFreeBoardReview(FreeBoardReviewDto freeBoardReview);

FreeBoardReviewServiceImpl.java

@Override 
	public void editFreeBoardReview(FreeBoardReviewDto freeBoardReview) {
		freeboardReviewMapper.editFreeBoardReview(freeBoardReview);
	}

FreeBoardReviewMapper.java

@Update("update FreeBoardReview "
        + "set replyContent = #{ replyContent } "
        + "where freeBoardReplyNo = #{ freeBoardReplyNo }")
void editFreeBoardReview(FreeBoardReviewDto freeBoardReview);

실행결과 수정이 잘 되는 것을 확인할 수 있다. 

사용자가 댓글을 수정하려다 수정 취소한 경우 -> 수정취소 버튼 클릭 이벤트처리 ( JSTL 사용 )

$(".cancel-edit-reply").on('click', function(event) {
    const freeBoardReplyNo = $(this).attr("data-reply-no");

    $('#reply-edit-area-' + freeBoardReplyNo).css('display', 'none');
    $('#reply-view-area-' + freeBoardReplyNo).css('display', '');

    currentEditFreeBoardReplyNo = null;

})

다음은 댓글 삭제 기능 구현할 차례이다.

댓글 삭제시 사용자가 삭제된 댓글임을 확인할 수 있도록 jsp를 작성해준다.

 <tbody>
    <c:forEach var="freeBoardReview" items="${freeBoard.freeBoardReviewList}">
        <tr style="text-align:center">
            <td style="width: 50px">${freeBoardReview.freeBoardReplyNo}</td>
            <td style="width: 150px">
            <c:choose>
                <c:when test="${ not freeBoardReview.replyDelete }">
                <a> ${ freeBoardReview.replyContent }</a>
                </c:when>
                <c:otherwise>
                <span class="replyDelete" style="color : gray"><< 삭제된 게시글입니다 >></span> 
                </c:otherwise>    
            </c:choose>  
            </td>     
            <td scope="col" style="width:200px"> ${ freeBoardReview.replyDelete? '' : sessionScope.loginuser.memberId } 
                                         <input type="hidden" name="memberNo" value="${ loginuser.memberId }"> 
            <td style="width: 150px">
                <fmt:formatDate value="${freeBoardReview.replyCreateDate}" pattern="yyyy-MM-dd HH:mm" />
            </td>
            <td>
                <a class="btn btn-sm btn-primary edit-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">댓글수정하기</a>
                <a class="btn btn-sm btn-primary delete-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">댓글삭제하기</a>
            </td>
        </tr>
        <tr>
            <td colspan="5">
                <div id="reply-edit-area-${freeBoardReview.freeBoardReplyNo}" style="display: none">
                    ${sessionScope.loginuser.memberId} &nbsp;&nbsp; [댓글 수정 시간 : ${freeBoardReview.replyCreateDate}] <br />
                    <br />
                    <form action="edit-reply" method="post" style="width: 105%; resize: none;">
                        <input type="hidden" name="freeBoardReplyNo" value="${freeBoardReview.freeBoardReplyNo}" />
                        <input type="hidden" name="freeBoardNo" value="${freeBoard.freeBoardNo}" />
                        <input type="hidden" name="pageNo" value="${pageNo}" />
                        <textarea name="replyContent" style="width: 70%; resize: none; border-radius: 80px" rows="2" maxlength="200" >${freeBoardReview.replyContent}</textarea>
                        <br />
                        <div class="btn btn-sm btn-primary">
                            <a class="update-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">수정완료</a>
                        </div>
                        <div class="btn btn-sm btn-primary">
                            <a class="cancel-edit-reply" data-reply-no="${freeBoardReview.freeBoardReplyNo}" href="javascript:void(0)" style="color: white">수정취소</a>
                        </div>
                    </form>
                </div>
            </td>
        </tr>
    </c:forEach>
</tbody>

 댓글 삭제하기 버튼 클릭 이벤트 처리

$(".delete-reply").on("click",function(event) {                    
    const freeBoardReplyNo = $(this).attr("data-reply-no");
    const yn = confirm(freeBoardReplyNo  + "번 댓글을 삭제할까요?");
    if (yn) {
        location.href='delete-reply?freeBoardReplyNo=' + freeBoardReplyNo +
                                    '&freeBoardNo=' + ${freeBoard.freeBoardNo} +
                                    '&pageNo=' + ${pageNo};
            }
})

FreeBoardReviewController.java

@GetMapping(path = {"/delete-reply"})
	public String deleteFreeBoardReview(int freeBoardReplyNo, int freeBoardNo, int pageNo) {
		
		freeBoardReviewService.deleteFreeBoardReview(freeBoardReplyNo);
		
		return String.format("redirect:freeboarddetail?freeBoardNo=%d&pageNo=%d", freeBoardNo, pageNo);
	}

FreeBoardReviewService.java

void deleteFreeBoardReview(int freeBoardReplyNo);

FreeBoardReviewServiceImpl.java

@Override  
public void deleteFreeBoardReview(int freeBoardReplyNo) {
    freeboardReviewMapper.deleteFreeBoardReview(freeBoardReplyNo);
}

FreeBoardReviewMapper.java

 @Update("update FreeBoardReview " 
        + "set replyDelete = true "
        + "where freeBoardReplyNo = #{ freeBoardReplyNo }")
void deleteFreeBoardReview(@Param("freeBoardReplyNo") int freeBoardReplyNo);

여기서도 게시글 삭제처럼 DB에서 Delete하는 것이 아니라 Update 처리로 데이터는 남기되 삭제한 것처럼 처리한다. 

실행결과 삭제 버튼을 누르면,

이렇게 팝업이 뜨고 확인을 누르면 삭제처리가 잘 되는 것을 확인할 수 있다.

 

// 문제점 발견 : 삭제하고 나서는 댓글 수정삭제 버튼이 안보여야함