기록방

18장 : 웹 페이지에서 댓글 수정하기 본문

FrameWork/Spring

18장 : 웹 페이지에서 댓글 수정하기

Soom_1n 2024. 7. 30. 18:14

길벗 IT도서에서 주관하는 코딩 자율학습단 8기 : Spring Boot 파트에 참여한 기록입니다 [ 목록 ]

18.1 댓글 수정의 개요

댓글 수정 뷰 페이지 만들고 JS의 이벤트를 통해 댓글 수정하기

  • 모달 창을 이용해서 댓글 수정 페이지 만들기

18.2 댓글 수정 뷰 페이지 만들기

18.2.1 수정 버튼과 모달 추가하기

<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">수정</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">
                <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 수정 폼 삽입하기

            <div class="modal-body">
                <!--댓글 수정 폼-->
                <form class="container" action="/articles/create" method="post">
                    <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>
            </div>

18.3 자바스크립트로 댓글 수정하기

  • 수정 폼에 기존 댓글 정보 가져오기
  • 댓글 정보를 JS 요청에 실어 REST API 호출 후 처리

18.3.1 트리거 데이터 전달하기

<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>
            </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">
                <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">
                <!--댓글 수정 폼-->
                <form class="container" action="/articles/create" method="post">
                    <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>
            </div>
        </div>
    </div>
</div>

<!--모달 이벤트 처리-->
<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 호출하고 응답 처리하기

{
        // 수정 완료 버튼 선택
        const commentUpdateBtn = document.querySelector("#comment-update-btn");
        // 클릭 이벤트 처리
        commentUpdateBtn.addEventListener("click", function() {
            const comment = {
                // 수정 댓글 객체 생성
                id: document.querySelector("#edit-comment-id").value,
                nickname: document.querySelector("#nickname").value,
                body: document.querySelector("#body").value,
                article_id: document.querySelector("#edit-comment-article-id").value,
            }
            console.log(comment);
            // 수정 REST API 호출
            const url = "/api/comments/" + comment.id;
            fetch(url, {
                method: "PATCH",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify(comment)
            }).then(response => {
                // HTTP 응답 코드에 따른 메시지 출력
                const msg = (response.ok) ? "댓글이 수정됐습니다." : "댓글 수정 실패..!";
                alert(msg);
                // 현재 페이지 새로 고침
                window.location.reload();
            })
        });
    }

🚀 1분 퀴즈

다음 설명 중 옳은 것을 모두 고르세요.

  1. 모달은 웹 페이지 내부에서 상위 레이어를 띄우는 방식으로 사용하는 창이다.
  2. show.bs.modal 이벤트는 모달이 보여진 다음 수행된다.
  3. HTML의 data-* 속성은 HTML 요소에 추가 정보를 저장하고 싶을 때 사용한다.
  4. 이벤트 핸들러란 특정 이벤트를 처리하는 함수다.
  5. JSON.stringify()는 문자열을 입력 받아 자바스크립트 객체로 반환한다.

⇒ 1, 3, 4

2) 모달이 보여지기 직전에 수행된다

5) 자바스크립트 객체(JSON)을 문자열로 변환한다.

✅ 셀프 체크

  • [트리거 버튼]을 클릭해 다음과 같은 부트스트랩 모달 창을 만드려고 합니다.
  • 다음 코드를 완성하세요
<h1>모달로 데이터 전달</h1>
<!-- 모달 트리거 버튼 -->
<button id="trigger-btn"
        data-bs-toggle="modal"
        data-bs-target="#exampleModal"
        data-custom-title="점심 뭐 먹지?"
        data-custom-text="돈가스 어떄">트리거 버튼</button>
<!-- 모달 -->
<div class="modal fade" id="exampleModal" tabindex="-1">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="modal-title">???</h1>
                <button type="button" class="btn-close"
                        data-bs-dismiss="modal"></button>
            </div>
            <div class="modal-body">
                <p id="modal-text">...</p>
            </div>
        </div>
    </div>
</div>

<script>
    {
        // 모달 요소 선택
        const modal = document.querySelector("#exampleModal");
        // 모달 이벤트 감지
        modal.addEventListener("show.bs.modal", function (event) {
            // 1. 트리거 버튼 선택
            const triggerBtn = event.relatedTarget;
            // 2. 데이터 가져오기
            const title = triggerBtn.getAttribute("data-custom-title");
            const text = triggerBtn.getAttribute("data-custom-text");
            // 3. 수정 폼에 데이터 반영
            document.querySelector("#modal-title").innerHTML = title;
            document.querySelector("#modal-text").innerHTML = text;
        });
    }
</script>

🏓 더 알아볼 내용

1. 부트스트랩

부트스트랩은 프론트엔드 개발 시 좀 더 빠르고 쉽게 코드를 작성할 수 있도록 해주는 도구입니다. 특징은 다음과 같습니다.

  • 반응형 웹 디자인을 위한 그리드 시스템을 포함하여 다양한 디자인 요소를 쉽게 사용할 수 있도록 도와줍니다.
  • 기본적인 HTML 요소들을 빠르게 스타일링하고, 버튼, 폼, 카드, 네비게이션 바, 모달 등의 다양한 컴포넌트를 포함하고 있어 개발자들이 쉽게 사용할 수 있습니다.
  • 자바스크립트 플러그인을 통해 인터랙티브한 요소들을 추가할 수 있습니다.

다음은 버튼을 만드는 부트스트랩 코드입니다. 클래스 지정을 위해 따로 선언하지 않아도 돼 매우 편리합니다. 이처럼 부트스트랩을 사용하면 코드를 쉽게 작성할 수 있습니다.

<button type="button" class="btn btn-primary">Primary 버튼</button>
<button type="button" class="btn btn-secondary">Secondary 버튼</button>
<button type="button" class="btn btn-success">Success 버튼</button>
<button type="button" class="btn btn-danger">Danger 버튼</button>

2. fetch()

fetch()는 자바스크립트에서 제공하는 기본 함수로 네트워크 요청을 만들기 위한 함수입니다. 프로미스(Promise)를 반환하며, 기본적으로 네트워크 요청을 비동기적으로 보냅니다. 간단한 GET 요청을 예로 들어보죠.

fetch('https://api.example.com/data')
    .then(response => {
        if (!response.ok) {
            throw new Error('Network response was not ok');
        }
        return response.json(); // JSON 형태로 응답 데이터 파싱
    })
    .then(data => {
        // 응답 데이터를 사용하여 원하는 작업 수행
        console.log(data);
    })
    .catch(error => {
        console.error('There was a problem with the fetch operation:', error);
    });

만약 GET 요청이 아니라 POST, PUT 요청일 때는 다음과 같이 처리할 수 있습니다.

fetch('https://api.example.com/data', {
    method: 'POST', // PUT
    headers: {
        'Content-Type': 'application/json',
        // 다른 필요한 헤더들을 추가할 수 있습니다.
    },
    body: JSON.stringify({ key: 'value' }), // 요청 본문 설정
})
    .then(response => response.json())
    .then(data => {
        console.log('Success:', data);
    })
    .catch(error => {
        console.error('Error:', error);
    });

3. 모달

모달이란 웹 페이지에서 새 창을 띄우지 않고, 현재 페이지 위에 레이어 형태로 나타나는 팝업 창을 말합니다. 주로 사용자에게 메시지를 전달하거나 추가적인 정보를 제공하기 위해 많이 사용됩니다.

일반적으로 모달은 다음과 같은 구성 요소를 가지고 있습니다.

  1. 타이틀 바(Title Bar): 모달창의 제목을 보여주는 부분입니다.
  2. 내용(Content): 모달창에 표시되는 메시지, 정보, 양식 등의 내용이 위치합니다.
  3. 닫기 버튼(Close Button): 모달창을 닫는 역할을 하는 버튼입니다.

부트스트랩에서 제공하는 기본 모달창 코드는 다음과 같습니다.

<!-- 버튼 클릭 시 모달 열기 -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal"
data-bs-target="#exampleModal">
    모달 열기
</button>

<!-- 모달 -->
<div class="modal fade" id="exampleModal" tabindex="-1"
aria-labelledby="exampleModalLabel" aria-hidden="true">
    <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">
                모달 내용.
                JavaScript
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-secondary"
                    data-bs-dismiss="modal">닫기</button>
                <button type="button" class="btn btn-primary">저장</button>
            </div>
        </div>
    </div>
</div>

4. querySelector() 메서드

querySelector() 메서드는 DOM(Document Object Model)에서 요소를 선택하기 위해 사용되는 메서드 중 하나로, 주어진 CSS 선택자에 해당하는 첫 번째 요소를 반환하고 만약 일치하는 요소가 없으면 null을 반환합니다. 이 메서드를 사용하면 HTML 문서 내에서 특정 요소를 선택하고 자바스크립트로 조작할 수 있습니다.

<!DOCTYPE html>
<html>
    <head>
        <title>querySelector 예시</title>
    </head>
    <body>
        <div id="example">
        <h1>제목</h1>
        <p>내용</p>
        </div>
        <script>
            // id가 'example'인 요소를 선택하여 변수에 저장
            const exampleDiv = document.querySelector('#example');
            // 선택한 요소의 내용을 변경
            exampleDiv.style.backgroundColor = 'lightblue';
        </script>
    </body>
</html>

위 코드에서 document.querySelector('#example')는 문서 내에서 id가 'example'인 요소를 선택하고, 이를 exampleDiv 변수에 할당합니다. 그 후에는 선택한 요소의 배경색을 바꾸는 등의 작업을 수행할 수 있습니다.

querySelector() 메서드는 CSS 선택자를 사용하기 때문에 클래스, 태그 이름, 아이디 등을 이용하여 요소를 선택할 수 있습니다. 예를 들어 .className, tagName, #idName과 같이 CSS 선택자를 활용하여 요소를 선택할 수 있습니다. 이를 통해 자바스크립트를 사용하여 원하는 요소를 조작하거나 스타일을 변경할 수 있습니다.

728x90