뷰
페이지를 만들고 자바스크립트
의 이벤트
처리를 통해 댓글을 수정.모달
기능을 이용해서 만듦.모달(modal)
은 웹 페이지에 새 창
을 띄우는 팝업
창과 달리 같은 웹 페이지 내부
에서 상위 레이어
를 띄우는 방식으로 사용하는 창.비활성
상태가 되고, 모달 창을 닫아야만 원래 화면으로 돌아갈 수 있음.부트스트랩
-> Components
-> Modal
Live demo
검색.Launch demo modal
버튼을 클릭해보면 모달 창이 뜨는 것을 확인할 수 있음._list.mustache
파일의 코드를 수정.수정
버튼은 닉네임 옆에 위치시킬거라 {{nickname}}
아래쪽에 <button>
태그를 삽입.<div class="card-header">
{{nickname}}
<!-- Button trigger modal (댓글 수정 모달) -->
<button type="button" class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#exampleModal">수정</button>
</div>
<div class="card-body">
{{body}}
</div>
수정
버튼 : 모달 트리거 버튼
수정
버튼을 클릭하면 모달이 실행.data-bs-toggle="modal"
토글 역할
)data-bs-target="#exampleModal"
id
의 모달 실행.<!-- 모달 -->
<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>
_list.mustache
제일 하단에 작성.
수정
버튼 클릭시 모달 창 생성되는 것을 확인.
<!-- 모달(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" 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>
<!-- Button trigger modal (댓글 수정 모달 트리거 버튼) -->
<button type="button" class="btn btn-sm btn-outline-success" data-bs-toggle="modal" data-bs-target="#comment-edit-modal">수정</button>
모달
의 id
를 comment-edit-modal
으로 수정.모달 트리거 버튼
의 data-bs-toggle
속성 값
도 같이 바꿔줌.폼
삽입하기.<form>
태그 사용.<form>
<!-- 닉네임 입력 -->
<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>
input
박스의 id를 edit-comment-nickname
으로 수정.edit-comment-body
으로 수정.comment-update-btn
으로 수정.수정
버튼 클릭시 뜨는 모달 창.폼
에 기존
댓글 데이터
를 가져오고, 이를 자바스크립트
요청에 실어서 REST API
를 호출
한 후 처리._list.mustache
<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-success" data-bs-toggle="modal" data-bs-target="#comment-edit-modal">수정</button>
</div>
<div class="card-body">
{{body}}
</div>
</div>
{{/commentDtos}}
</div>
댓글
이 {{#commentDtos}}...{{/commentDtos}}
머스테치 문법으로 감싸져 있음.commentDtos
에 저장된 commentDto
의 수만큼 반복
해서 댓글 데이터
를 출력
하라는 의미.commentDto
에 저장된 데이터
를 모달 트리거 버튼
의 속성 값
으로 가져오기.<button type="button" class="btn btn-sm btn-outline-success"
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}}
값을 저장.{{nickname}}
값을 저장.{{body}}
값을 저장.{{articleId}}
값을 저장.data-
로 시작하는 속성을 데이터 속성
이라고 함.데이터 속성
은 HTML 요소
에 추가 정보
를 저장하고 싶을 때 사용.하나의 요소
에 여러 데이터 속성
을 사용할 수 있음.data-
로 시작하고 그 다음은 마음대로 작성._list.mustache
// 모달 이벤트 처리
<script>
{
}
</script>
데이터
를 모달
의 각 폼
에 출력.모달 이벤트 처리
라고 함.<!-- 모달 이벤트 처리 -->
<script>
{ // 모달 요소 선택.
const commentEditModal = document.querySelector("#comment-edit-modal");
commentEditModal.addEventListener("show.bs.modal", function (event) {
});
}
</script>
const commentEditModal = document.querySelector("#comment-edit-modal");
querySelector()
메서드로 모달을 선택하고 변수에 저장.commentEditModal.addEventListener("show.bs.modal", function (event) {
// 형식
요소명.addEventListener("이벤트 타입", 이벤트 처리 함수)
show.bs.modal
은 모달 동작의 이벤트 타입
을 뜻함. (# 5번 참고
)function (event)
이벤트
를 매개변수
로 받아 실행
되는 함수.이벤트 처리
를 담당하는 함수를 이벤트 핸들러(event handler)
라고 함."show.bs.modal", function (event)
의 의미.※
기본적으로 자바스크립트 이벤트 핸들러
는 event
매개변수를 자동
으로 전달
함.<!-- 모달 이벤트 처리 -->
<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-articleId");
// 수정 폼에 데이터 반영. (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>
1번
※
show.bs.modal
이벤트에서 event.target은 모달
이 되고, event.relatedTarget은 트리거 버튼
이 됨.2번
triggerBtn.getAttribute()
를 사용해서 각 변수에 저장.id
의 경우 data-bs-id
속성에 저장했음.3번
querySelector()
를 사용해서 폼
을 선택하고 해당 요소
의 value
속성에 앞에서 가져온 값
을 저장.수정 완료
버튼을 누르면 REST API
를 호출.// 모달 이벤트 처리
<script>
{
// 생략
}
{
// 수정 완료 버튼 선택.
const commentUpdateBtn = document.querySelector("#comment-update-btn");
// 클릭 이벤트 처리
commentUpdateBtn.addEventListener("click", function () {
});
}
</script>
querySelector()
메서드를 사용해서 수정 완료 버튼(comment-update-btn
)을 선택해서 변수에 저장.addEventListener()
로 수정 완료 버튼에 클릭
이벤트가 발생하면 함수(댓글 수정)가 실행.키(key)
는 id
, nickname
, body
, articleId
.값
은 querySelector()
로 댓글 수정 폼
의 각 요소
를 선택해서 value
값을 가져옴.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);
});
commentUpdateBtn.addEventListener("click", function () {
// 수정 댓글 객체 생성. (객체 리터럴 방식)
const comment = {
// 생략
// 댓글 수정 REST API 호출.
const url = "/api/comments/" + comment.id; (1번)
fetch(url, { (2번)
method: "PATCH" // PATCH 요청.
, headers: { // 전송 데이터 타입 정보(JSON)
"Content-Type": "application/json"
},
body: JSON.stringify(comment) // comment 객체를 JSON 문자열로 변환해서 전송.
}).then(response => { (3번)
// HTTP 응답 코드에 따른 메시지 출력
const msg = response.ok ? "댓글 수정 완료!" : "댓글 수정 실패...!"
alert(msg);
// 현재 페이지 새로고침.
window.location.reload();
});
});
1번
API
주소를 저장.API
주소에서 댓글의 id는 매번 변경되므로 comment.id
(변수)로 처리.2번
첫 번째
전달값으로 API
주소가 저장되어 있는 url
을 넘김.두 번째
전달값으로 요청 메서드
, 헤더 정보
, 전송 본문
을 넘김.객체
를 JSON
형태로 변환
해서 전달하기 위해서 JSON.stringify()
메서드 사용.3번
response
는 API
요청을 보내고 받은 응답 객체
.msg
를 alert()
함수로 출력.이벤트 타입 | 설명 |
---|---|
show.bs.modal | - 모달이 표시되기 직전에 실행되는 이벤트. |
shown.bs.modal | - 모달이 표시된 후 실행되는 이벤트. |
hide.bs.modal | - 모달이 숨겨지기 직전에 실행되는 이벤트. |
hidden.bs.modal | - 모달이 숨겨진 후 실행되는 이벤트. |