본문 바로가기

⭐ SpringBoot/𝄜 게시판 with SpringBoot

24. 댓글 등록 with JavaScript

요약

댓글 등록을 위한 뷰 페이지를 만들었고, 댓글 작성 버튼이 클릭 되었을때 그 신호를 감지하기 위한 코드도 생성 하였다. 해당 버튼을 변수화 하여 그 버튼에서 클릭 이벤트를 감지하게 하고 // 새 댓글 객체 생성 내용이 실행되게 하였다. 그때 쿼리 셀렉터를 통해서 nickname과 body, article-id의 값을 가지고 왔다. 그리고 해당 값을 객체로 생성 후 fetch()라는 API를 통해서 REST API를 POST 방식으로 JSON 데이터를 던져서 호출 하였다. 그래서 그 응답이 들어오면 그 응답으로 메세지를 출력하거나 페이지를 새로고침 하는등의 자바스크립트 코드를 완성 하였다.

# 댓글 등록 뷰 페이지를 만들고, REST API를 호출하여 새 댓글을 추가한다.

 

댓글등록 작업 진행 흐름

1. 댓글 폼 작성

2. 전송 버튼이 클릭 되었을때 REST API 요청이 보내지도록 한다.

이를위해 몇가지 JavaScript API를 사용할 것인데,

버튼 변수화를 위해 document.querySelector(),

클릭시 특정 동작 수행을 위해 addEventListener,

마지막 REST API 호출을 위해 fetch() API를 사용 한다.

또 추가로 댓글을 Javascript를 객체로 만드는 방법과 이렇게 만들어진 JavaScript 객체를 JSON으로 변환하는 코드또한 수행 한다.

댓글 생성 뷰 페이지

이전에 생성한 _new.mustache 파일을 열고 코드를 작성한다. 부트스트립에서 제공하는 card를 활용하여 작성 한다.

new.mustache 전체 코드

<div class="card m-2" id="comments-new">
    <div class="card-body">
        <!-- 댓글 작성 폼 -->
        <form>
            <!-- 닉네임 입력-->
            <div class="bm-3">
                <label class="form-label">닉네임</label>
                <input class="form-control form-control-sm" id="new-comment-nickname">
            </div>
            <!-- 댓글 본문 입력 -->
            <div class="mb-3">
                <label class="form-label">댓글 내용</label>
                <textarea class="form-control form-control-sm" rows="3" id="new-comment-body"></textarea>
            </div>

            <!-- 히든 인풋 -->
            {{#article}}
                <input type="hidden" id="new-comment-article-id" value="{{id}}">
            {{/article}}

            <!-- 전송 버튼 -->
            <button type="button" class="btn btn-outline-primary btn-sm" id="comment-create-btn">댓글 작성</button>
        </form>
    </div>
</div>

아래의 크림처럼 댓글이 작성될수 있도록하는 연결고리가 필요한데 그것을 JavaScript를 통해서 작성을 진행 한다.

자바 스크립트는 해당 new.mustache 파일의  가장 마지막 부분에 작성 한다.

자바스크립트 코드는 <script></script> 안에 작성을 해준다.

자바 스크립트와 html 파일이 함께 작성된 new.mustache 파일

<div class="card m-2" id="comments-new">
    <div class="card-body">
        <!-- 댓글 작성 폼 -->
        <form>
            <!-- 닉네임 입력-->
            <div class="bm-3">
                <label class="form-label">닉네임</label>
                <input class="form-control form-control-sm" id="new-comment-nickname">
            </div>
            <!-- 댓글 본문 입력 -->
            <div class="mb-3">
                <label class="form-label">댓글 내용</label>
                <textarea class="form-control form-control-sm" rows="3" id="new-comment-body"></textarea>
            </div>

            <!-- 히든 인풋 -->
            {{#article}}
                <input type="hidden" id="new-comment-article-id" value="{{id}}">
            {{/article}}

            <!-- 전송 버튼 -->
            <button type="button" class="btn btn-outline-primary btn-sm" id="comment-create-btn">댓글 작성</button>
        </form>
    </div>
</div>

<script>
    {
        // 댓글 생성 버튼을 변수화 (id가 comment-create-btn인 대상을 선택해서 가져옴)
        const commentCreateBtn = document.querySelector("#comment-create-btn");

        // 버튼 클릭 이벤트를 감지!!
        commentCreateBtn.addEventListener("click", function() {
            // 새 댓글 객체 생성
            const comment = {
                nickname: document.querySelector("#new-comment-nickname").value,
                body: document.querySelector("#new-comment-body").value,
                article_id: document.querySelector("#new-comment-article-id").value,
            };

            // 댓글 객체 출력
            console.log(comment);

            // fetch() - Talend API 요청을 JavaScript로 보내준다!
            const url = "/api/articles/" + comment.article_id + "/comments";
            fetch(url, {
                method: "post",     // POST 요청을 보낸다.
                body: JSON.stringify(comment),     // comment JS 객체를 JSON으로 변경하여 보냄
                headers: {
                    "Content-Type": "application/json"
                }
            }).then(response => {
            // http 응답 코드에 따른 메세지 출력
            const msg = (response.ok) ? "댓글이 등록 되었습니다." : "댓글 등록 실패..!";
            alert(msg);
            // 현재 페이지 새로고침
            window.location.reload();
            });
        });
    }
</script>