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();
});
});
}
짱신기해..
'web +a' 카테고리의 다른 글
스프링부트 ~28 | oracle DB연동 (0) | 2022.07.31 |
---|---|
스프링부트 ~27 | 댓글 삭제 (+ JS) (0) | 2022.07.29 |
스프링부트 ~25 | 댓글 등록 뷰페이지 (javascript 이용!) (0) | 2022.07.27 |
스프링부트 ~24 | 댓글목록 뷰페이지 만들기 => 게시글 상세페이지에서 확인 (0) | 2022.07.27 |
Dto와 Entity (0) | 2022.07.27 |