1. 댓글 데이터 구조
댓글 데이터 구조는 게시물 1개에서 commentList 배열 형식으로 진행 하였다.
{
"no":1,
"title":"Bird of Paradise",
"content":"Change Packing Material on Right Foot",
"commentList": [
{
"no": 1,
"name": "작성자1",
"comment": "ㅋㅋ",
"date": "2022-02-20"
},
{
"no": 2,
"name": "작성자2",
"comment": "ㅎㅎㅎ",
"date": "2022-02-20"
}
],
"date":"2021-07-12"
}
2. 댓글 개수 출력
댓글이 존재하면 게시물 제목 옆에 댓글의 개수가 출력되게 된다.
//로컬스토리지의 내용을 읽어서 테이블에 데이터를 바인딩시킨다.
function boardListAction() {
const dataTable = document.getElementById('dataTable');
boardListRemove();
if(_storageData) {
for(let i=_start; i<_limit; i++) {
if(_storageData[i]) {
let tr = document.createElement("tr");
let th_no = document.createElement("th");
let td_title = document.createElement("td");
let td_content = document.createElement("td");
let td_date = document.createElement("td");
let td_action = document.createElement("td");
th_no.setAttribute('scope', 'row');
th_no.innerText = _storageData[i].no;
//commentList 배열이 존재하면 게시물 제목 옆에 댓글 개수를 함께 출력해준다.
const title = _storageData[i].commentList ? _storageData[i].title + ' (' + _storageData[i].commentList.length + ')' : _storageData[i].title;
td_title.innerText = title;
td_content.innerText = _storageData[i].content.length > 20 ? _storageData[i].content.substr(0, 20) + '...' : _storageData[i].content; //20글자 뒤에는 ... 으로 처리
td_date.innerText = _storageData[i].date;
td_action.innerHTML = `
<i class="bi bi-file-text" onClick="detailItem(${_storageData[i].no})" style="cursor: pointer;"></i>
<i class="bi bi-trash-fill" onClick="deleteItem(${_storageData[i].no})" style="cursor: pointer;"></i>
`;
tr.appendChild(th_no);
tr.appendChild(td_title);
tr.appendChild(td_content);
tr.appendChild(td_date);
tr.appendChild(td_action);
dataTable.appendChild(tr);
}
}
}
}
boardListAction 함수에서 title 바인딩 되는 부분에서 commentList배열 존재 여부로 댓글 개수를 함께 출력해준다.
3. 댓글 목록 출력
상세 페이지에서 댓글 목록을 출력하기위해서 comment.html 템플릿을 먼저 만들어 주었다.
<div id="commnet-area" class="modal-footer" style="display: flex; align-items: baseline; flex-direction: row;">
<ul id="dataComment" style="width: 100%; max-height:200px; list-style-type : none; padding: 0; overflow-y: auto;"></ul>
<section style="display: flex; width: 100%;">
<div style="margin: 2%;">
<i class="bi bi-person-circle fa-lg" style="color:gray"></i>
</div>
<input id="name" type="text" class="form-control" placeholder="이름" aria-label="이름" aria-describedby="basic-addon1" style="width: 15%;">
</section>
<section style="display: flex; width: 100%;">
<textarea id="comment" class="form-control" placeholder="댓글" aria-label="With textarea" rows="1"></textarea>
<button type="button" class="btn btn-primary" onclick="commentSave()" style="min-width: 55px; margin: 0 1%;">쓰기</button>
</section>
</div>
기존 modal.html 에서 comment.html 부분을 삽입한다.
<div class="modal" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"><span id="titleType"></span></h5>
<i class="fa-solid fa-xmark" onclick="modalClose()" style="cursor: pointer;"></i>
</div>
<div class="modal-body">
<div class="input-group mb-3">
<input id="title" type="text" class="form-control" placeholder="제목" aria-label="제목" aria-describedby="basic-addon1">
</div>
<textarea id="content" class="form-control" placeholder="내용" aria-label="With textarea" rows="10"></textarea>
</div>
<div w3-include-html="./comment.html"></div> <!-- comment.html 삽입 -->
<div class="modal-footer">
<button id="modalButton" type="button" class="btn btn-primary" onclick="modalAction()"></button>
<button type="button" class="btn btn-secondary" onclick="modalClose()">닫기</button>
</div>
</div>
</div>
</div>
//댓글 목록 불러오기
function commentListAction(commentList) {
//기존 댓글 목록 지움
let dataComment = document.getElementById('dataComment');
while (dataComment.hasChildNodes() ) {
dataComment.removeChild( dataComment.firstChild);
}
commentList.map(data => {
let li = document.createElement("li");
li.innerHTML = `
<i class="bi bi-person-circle" style="color:gray">`+data.name + ` ` + data.date+`</i>
<div style="display: flex; justify-content: space-between;">
<p class="readComment">`+data.comment+`</p>
</div>
<hr>
`;
dataComment.appendChild(li);
});
}
commentListAction 함수에서 댓글 목록을 바인딩 시켜준다.
댓글을 불러오기 전에 html화면상에서 이전 댓글을 지워준다.
function detailItem(no) {
modalOpen('Detail');
let detail = _storageData.filter((data) => {
return data.no == no;
});
let title = document.getElementById('title');
let content = document.getElementById('content');
title.value = detail[0].title;
content.value = detail[0].content;
title.readOnly = true;
content.readOnly = true;
_boardNo = no;
if(detail[0].commentList) {
commentListAction(detail[0].commentList);
} else {
//기존 댓글 목록 지움
let dataComment = document.getElementById('dataComment');
while (dataComment.hasChildNodes() ) {
dataComment.removeChild( dataComment.firstChild);
}
}
}
detailItem (글 상세 조회 함수) 에서 commentList가 존재하면 commentListAction 함수를 실행 시켜주고
commentList가 존재하지 않으면 이곳에서도 html 화면상에서 기존 댓글목록을 지워주는 처리를 하였다.
4. 댓글 쓰기
<section style="display: flex; width: 100%;">
<textarea id="comment" class="form-control" placeholder="댓글" aria-label="With textarea" rows="1"></textarea>
<button type="button" class="btn btn-primary" onclick="commentSave()" style="min-width: 55px; margin: 0 1%;">쓰기</button>
</section>
textarea 영역에 작성된 문자를 commentSave 함수에서 댓글을 작성해 준다.
//댓글 등록
function commentSave() {
const name = document.getElementById('name').value;
let comment = document.getElementById('comment').value;
let date = new Date();
date = dateFormat(date);
let detail = _storageData.filter((data) => {
return data.no == _boardNo;
});
if(detail[0].commentList == undefined) {
detail[0].commentList = new Array();
detail[0].commentList.push({
no: 1,
name: name,
comment: comment,
date: date
});
} else {
let lastIndex = detail[0].commentList.slice(-1)[0].no;
detail[0].commentList =
[
...detail[0].commentList,
{
no: lastIndex+1,
name: name,
comment: comment,
date: date
}
];
};
window.localStorage.setItem('storageList',JSON.stringify(_storageData));
document.getElementById('comment').value = '';
commentListAction(detail[0].commentList);
boardListAction();
document.getElementById('dataComment').scrollTop = document.getElementById('dataComment').scrollHeight;
}
commentSave 함수에서 먼저 댓글이 추가될 객체를 No로 찾아서 detail 변수에 담아 놓는다.
detail 변수에 commentList 배열 존재 여부로 최초로 작성되는 댓글에는 commentList 배열 생성 후에 댓글을 추가해 준다.
댓글 작성 후에는 댓글 목록인 ul 태그의 dataComment 영역의 스크롤을 최 하단으로 내려준다.
'개발이야기 > JavaScript' 카테고리의 다른 글
[VanilaJs] 게시판 만들기 (4) - 글 상세보기와 수정 (0) | 2022.07.03 |
---|---|
[VanilaJs] 게시판 만들기 (3) - 글 삭제와 등록 (1) | 2022.07.01 |
[VanilaJs] 게시판 만들기 (2) - Modal창 마크업 및 동작 (0) | 2022.06.28 |
[VanilaJs] 게시판 만들기 (1) - 글 목록 조회 및 페이징 처리 (0) | 2022.06.28 |