본문 바로가기

web +a

스프링부트 ~26 | 역시 js로 댓글수정기능 추가 (+모달 사용!)

Intro

 

댓글 수정 페이지뷰를 만들고 (이번에도) javascript의 이벤트 처리를 통해 댓글을 수정해보자.

 

∨ 미리 생각해보기 : 댓글생성때는 rest api를 호출하기 위해 fetch() 기능을 사용했다. 수정도 rest api 요청을 보내는 건 마찬가지니까 똑같이 fetch(url, {보낼내용}).then(response => {응답후행동}) 이런 코드를 사용하지 않을까 싶다!! 이 rest api 호출부를 수정버튼.클릭리스너 블록 안에 넣는것이 아닐까요로리링~!?

 

 

 

+ 새롭게 해볼 것들!

∨ 부트스트랩5가 제공하는 Modal 사용

∨ 이를 제어하는 js코드 사용

 


먼저 가볍게 수정버튼 넣고 시쟉 ~~!

더보기

수정..기능..추가...니까.. 댓글 옆에 수정버튼 넣어야겠지.. 

그냥.. 저번에 작성한... _list.mustache 파일에.. {{nickname}} 옆에 가도록.. 버튼 넣어주면 된다..

<button class="btn btn-sm btn-outline-primary">수정</button>

 

이 수정버튼을 누르면 수정창이 떠야 한다. 어카지?

=> 별도로 수정창이 뿅 뜨는 것은 'Modal'이다!

Modal 기능을 사용해보자!!!!! 부트스트랩에서 modal 검색 고고싱!!

 

 Modal

방금 만든 수정버튼에 모달을 적용해보자.

부트스트랩에서 가져온 코드를 보면 <button>태그가 모달 트리거 용도로 존재하는데, 

그걸 수정버튼으로 갖다두면 된다.

더보기

그러니까 이 코드를 용도에 맞게 바꿔쓰면 된다.

디자인도 바꾸고 내용도 바꾸고..

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Launch demo modal
</button>

 

또한 Modal 부분도 잘 변경해서 사용하면 된다.

더보기

변경 예시) 

 id가 exampleModal로 되어있는데 comment-edit-modal로 바꿔주었다.

 footer가 필요없어서 footer는 날려줬다.

∨ 내용부분에는 수정폼을 작성해야 하므로 폼을 넣어줬다.

 

cf) 아래 코드는 부트스트랩에서 가져온 Modal 코드 그대로다.

<!-- Modal -->
<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">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        ...
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>

 

 

● Modal에 데이터 전달해서 사용하기

 

∨ 먼저 생각해보기

수정폼에 기존 데이터도 함께 표시되도록 해야 좋을 것이다.

어떻게 데이터를 가져다가 수정폼에 표시되도록 할 수 있을까..?

트리거인 수정버튼을 누르면 데이터를 가져와서 모달에서 쓸 수 있게 해야한다.

그리고 일단 수정버튼을 눌렀을 때 이벤트 처리하는 거니까 이벤트 리스너를 쓰면 되지 않을까? 

 

step1 : 버튼에 데이터 전달

부트스트랩 코드 예시를 보고 사용방법을 터득해보자.

더보기

∨ 부트스트랩에 예시로 나온 javascript 코드를 보면 이러한 구조다.

- 모달을 가져와서 이벤트 리스너를 통해 'show.bs.modal' 이벤트가 발생하면 function(event) {...} 수행

- 수행하는 기능 : 파라미터로 전달된 event에다가 .relatedTarget으로 모달의 트리거가 되는 button을 가져올 수 있나보다. 그리고 botton.getAttribute('data-bs-whatever')를 통해 무언가 데이터를 받아낼 수 있나보다.  

var exampleModal = document.getElementById('exampleModal')
exampleModal.addEventListener('show.bs.modal', function (event) {
  // Button that triggered the modal
  var button = event.relatedTarget
  // Extract info from data-bs-* attributes
  var recipient = button.getAttribute('data-bs-whatever')
  // If necessary, you could initiate an AJAX request here
  // and then do the updating in a callback.
  //
  // Update the modal's content.
  var modalTitle = exampleModal.querySelector('.modal-title')
  var modalBodyInput = exampleModal.querySelector('.modal-body input')

  modalTitle.textContent = 'New message to ' + recipient
  modalBodyInput.value = recipient
})

 

부트스트랩에서 가져온 버튼예시를 보면 이렇게 되어있다.

뭔가 data-bs-whatever="~~"에 들어간 데이터가 전달되는 것 같다. 

<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal" data-bs-whatever="@mdo">Open modal for @mdo</button>

 

 

 

아하... 옥헤이.. 

버튼 속성에다가 data-bs-whatever 변수를 넣어두면, 데이터를 이벤트에 전달할수 있나보다!!!!

 

 

그러면 우리가 전달하고싶은 댓글 데이터를 data-bs-whatever 변수에 넣어주어야겠다.

댓글의 데이터는 'id, nickname, body, article_id'가 있었다. 이것들 중에 수정폼에 전달해야 할 것은?

∨ 이벤트 처리를 위해 댓글의 고유 id도 필요할 것 같다.

∨ 기존 내용 표시를 위해 nickname과 body는 딱봐도 필요하다.

∨ article_id는.. 필요한가? 안 필요할 것 같다..

 

 

버튼의 이벤트에 필요한 데이터를 파악했으면,

트리거 버튼 속성에다가 변수를 명시해주자.

        <!-- 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>

음.. 이제 버튼의 이벤트에서 data-bs-id, data-bs-nickname, data-bs-body 데이터를 사용할 수 있게 되었다! 얏호~

 

 

step2 : 이벤트 리스너 작성

이제 javascript로 이벤트 리스너만 슉 작성해주면 된다. 

 

스크립트 내용은 다음과 같다.

↓ 먼저 현재 문서에서 모달요소를 선택해준다. 모달 id는 comment-edit-modal이었다.

↓ 모달의 이벤트를 감지한다. 이벤트 이름은 show.bs.modal인가보다.

↓ 트리거 버튼을 변수에 담는다. 기억! 우린 트리거 버튼의 속성에 필요한 데이터를 담아뒀었다. 트리거 버튼을 가져오는 방법은, 매개변수로 전달한 event에 relatedTarget으로 가져올 수 있나보다.

↓ 트리거버튼.getAttribute("변수") 이렇게 데이터 가져와서 쓰면 된다.

<!-- 모달 이벤트 처리 -->
<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;
  });
}
</script>

↑ 가져온 데이터를 폼에 반영하는 법 부연설명

: document.querySelector("#edit-comment-nickname").value = nickname; 이렇게 데이터를 반영하고 있다. 

: 댓글수정 폼 입력하는 컴포넌트의 id를 통해 값을 넣어주고 있는 것이다.

: 가령 닉네임을 표시해준다고 하자. document에서 querySelector로 닉네임 입력하는 컴포넌트의 id를 통해 해당 컴포넌트를 선택해준다. 그리고 그 컴포넌트의 value에 원하는 값(가져온 nickname 데이터)을 할당하면 되는 것이다.

 

 

 


 수정완료 버튼 => REST API 호출

이제 이것만 해결하면 된다.

js를 통해 rest api를 호출하는 건 바로 어제 공부했던 거다. 

2022.07.27 - [web +a] - 스프링부트 ~25 | 댓글 등록 뷰페이지 (javascript 이용!)

 

단순히 js의 fetch()기능을 쓰면 된다고 했다!

recall) fetch(url, {보낼내용}).then(response => {응답후행동}) : rest api 호출

 

 

※ 모달에서 수정완료 버튼을 처리하는 거니까!! 모달 이벤트 리스너 함수 안에 rest api 처리를 해주어야겠지!!

아~~주 당연스럽게 모달 이벤트 처리하는 부분에다가 작성하도록 하자. 수정완료 버튼 클릭시 rest api 호출 보내는 부분을 중괄호로 묶어주면 되겠다.

 

 

즉 아래 코드묶음을 모달이벤트 처리 함수 내부에 넣어준다.

∨ 수정완료 버튼을 가져온 뒤 해당 버튼에대한 클릭이벤트를 처리한다.

↓ 입력폼에 입력한 데이터를 querySelector로 가져와서 수정 댓글 객체를 생성한다. 당연히 히든인풋인 경우도 그냥 id를 통해 가져올 수 있다.

↓ 그리고 fetch()메서드를 통해 rest api 호출을 보낸다!

recall) 해당 url에 대한 @PatchMapping을 통해 댓글수정이 일어난다. 컨트롤러에서 구현했던 것을 기억하자. 

{
  // 수정 완료 버튼
  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();
    });
  });
}

 

 

 


짱신기해..

 

 

반응형
다른 블로그