댓글 삭제 with JS

OneTwoThree·2022년 10월 24일
0
post-thumbnail

유튜브

댓글 삭제 기능을 만들어보자

수정 버튼 옆에 삭제 버튼을 추가해주자

<div id="comments-list">
    {{#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>
                <!-- 댓글 삭제 버튼 -->
                <button type="button"
                        class="btn btn-sm btn-outline-danger comment-delete-btn"
                        data-comment-id="{{id}}">삭제</button>
            </div>
            <div class="card-body">
                {{body}}
            </div>
        </div>
    {{/commentDtos}}
</div>

<!-- Modal -->
<div class="modal fade" id="comment-edit-modal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">댓글 수정</h5>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <!-- 댓글 수정 폼-->
                <form>
                    <!-- 닉네임 입력 -->
                    <div class="mb-3">
                        <label class="form-label">닉네임</label>
                        <input type="text" class="form-control form-control-sm" id="edit-comment-nickname">
                    </div>
                    <!-- 댓글 본문 입력 -->
                    <div class="mb-3">
                        <label class="form-label">댓글 내용</label>
                        <textarea type="text" class="form-control form-control-sm" 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-outline-primary btn-sm" id="comment-update-btn">수정 완료</button>
                </form>
            </div>
        </div>
    </div>
</div>

<!-- 모달 이벤트 처리 -->
<Script>
{
  // 모달 요소 선택
  const commentEditModal = document.querySelector("#comment-edit-modal");
  // 모달 이벤트 감지
  commentEditModal.addEventListener("show.bs.modal", function(event) {
    // 트리거 버튼 선택
    const triggerBtn = event.relatedTarget;
    // 데이터 가져오기
    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");
    //console.log(`${id}, ${nickname}, ${body}, ${articleId}`);
    // 데이터를 반영
    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;
  });
}
{
  // 수정 완료 버튼
  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,
      article_id: document.querySelector("#edit-comment-article-id").value
    };
    console.log(comment);
    // 수정 REST API 호출 - fetch()
    const url = "/api/comments/" + comment.id;
    fetch(url, {
      method: "PATCH",
      body: JSON.stringify(comment),
      headers: {
        "Content-Type": "application/json"
      }
    }).then(response => {
      // http 응답 코드에 따른 메시지 출력
      const msg = (response.ok) ? "댓글이 수정 되었습니다." : "댓글 수정 실패..!";
      alert(msg);
      // 현재 페이지를 새로고침
      window.location.reload();
    });
  });
}

</script>

<!-- 댓글 삭제 -->
<script>
{
    // 삭제 버튼 선택, 여러개의 묶음 가져옴
    const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");

    // 삭제 버튼 이벤트 처리
    commentDeleteBtns.forEach(btn => {
        //각 버튼의 이벤트 처리를 등록한다
        btn.addEventListener("click",(event) => {
            // 이벤트 발생 요소 선택
            const commentDeleteBtn = event.srcElement;

            //삭제하려는 댓글의 id를 가져오자
            const commentId = commentDeleteBtn.getAttribute("data-comment-id");
            console.log(`삭제 버튼 클릭 : ${commentId}번 댓글`); //자바스크립트 백틱 문자열 (키보드 왼쪽 맨위에 있는 ` 이거임)
            // "삭제 버튼 클릭 :" + commentId + "번 댓글" 이거랑 같음

            // 삭제 API 호출 및 처리
            const url = `/api/comments/${commentId}`; // 자바스크립트 백틱 문자열에 ${}로 변수 삽입가능
            fetch(url,{
                method : "DELETE",
            }).then(response => {
                // 댓글 삭제 실패 처리
                if (!response.ok) {
                    alert("댓글 삭제 실패..!");
                    return;
                }

                //삭제 성공 시, 댓글을 화면에서 지움!
                const target = document.querySelector(`#comments-${commentId}`);
                target.remove();


            });


        });
    });
}

</script>

전체코드이고 주석을 참고하며 보면 된다.

<!-- 댓글 삭제 버튼 -->
                <button type="button"
                        class="btn btn-sm btn-outline-danger comment-delete-btn"
                        data-comment-id="{{id}}">삭제</button>

삭제 버튼은 이렇게 만들었다.

{
    // 삭제 버튼 선택, 여러개의 묶음 가져옴
    const commentDeleteBtns = document.querySelectorAll(".comment-delete-btn");

    // 삭제 버튼 이벤트 처리
    commentDeleteBtns.forEach(btn => {
        //각 버튼의 이벤트 처리를 등록한다
        btn.addEventListener("click",(event) => {
            // 이벤트 발생 요소 선택
            const commentDeleteBtn = event.srcElement;

            //삭제하려는 댓글의 id를 가져오자
            const commentId = commentDeleteBtn.getAttribute("data-comment-id");
            console.log(`삭제 버튼 클릭 : ${commentId}번 댓글`); //자바스크립트 백틱 문자열 (키보드 왼쪽 맨위에 있는 ` 이거임)
            // "삭제 버튼 클릭 :" + commentId + "번 댓글" 이거랑 같음

            // 삭제 API 호출 및 처리
            const url = `/api/comments/${commentId}`; // 자바스크립트 백틱 문자열에 ${}로 변수 삽입가능
            fetch(url,{
                method : "DELETE",
            }).then(response => {
                // 댓글 삭제 실패 처리
                if (!response.ok) {
                    alert("댓글 삭제 실패..!");
                    return;
                }

                //삭제 성공 시, 댓글을 화면에서 지움!
                const target = document.querySelector(`#comments-${commentId}`);
                target.remove();


            });


        });
    });
}

자바스크립트 코드이다.
querySelectorAll로 버튼의 그룹을 가져온다.
querySelector로 할 경우 맨 위의 버튼만 선택하기 때문에 All로 해줘야 한다.
이벤트 처리를 위해 리스너를 등록해준다.
처리하는 부분은 전에 한것과 유사하다.
차이점은 response를 받은 후에 페이지를 새로고침 하지 않고 remove()를 통해 html 요소를 화면에서 삭제해 줬다. 이렇게 하면 페이지를 새로고침 하지 않는다는 차이가 있다.
reponse를 받고 나서 새로고침 하면 다시 request 보내고 response 받아서 db에 수정된 내용이 반영되는 것이고 이건 JS 코드를 통해 html 요소를 지워버린 것이다.

그리고 JS 코드에서 백틱 문자열을 사용한다. 백틱 문자열을 사용하면 문자열 내부에 ${}로 변수를 집어넣을 수 있다.

요약

  • 삭제 버튼 추가
  • querySelectorAll을 통해 모든 삭제 버튼을 가져온다
  • 버튼을 처리하기 위해 forEach로 반복문을 돌렸다
  • fetch로 삭제 요청을 보냈다
  • 백틱 문자열로 변수를 문자열 안에 넣었다
  • 새로고침을 하지 않고 문서 상에서 대상을 직접 삭제했다

참고사항

0개의 댓글