🔎 댓글 더보기 처리 이어서..
reply.js 일부
$(function() {
getList: function(param, callback, error) {
var bno = param.bno;
var rnoStr = param.rno ? "/" + param.rno : "";
var url = "/replies/more/" + bno + rnoStr;
$.getJSON(url, function(result) {
if(callback) {
callback(result);
}
}).fail(function(xhr, status, er) {
if(error) {
error(er);
}
});
}
});
🔶 getList()의 변수들 수정.
get.jsp 일부
$(function() {
var bno = <c:out value="${board.bno}"/>;
var replyUL = $(".chat");
var pageNum = 1;
showList(76); // 현재 163878 게시글의 댓글 다음 페이지
function showList(rno) {
replyService.getList({bno:bno, rno:rno}, function(list) {
// 댓글 목록 출력
console.log(list);
// 댓글 썼을 때 마지막 페이지 봐야 함.
//if(page == -1) showList(result.realEnd);
var str = "";
for(var i in list) {
str += '<li class="list-group-item" data-rno="' + list[i].rno + '">';
str += ' <div class="header">';
str += ' <strong>' + list[i].replyer + '</strong>';
str += ' <small class="float-right">' + replyService.displayTime(list[i].replyDate) + '</small>';
str += ' </div>';
str += ' <p class="mt-2">' + list[i].reply + '</p>';
str += '</li>';
}
replyUL.html(replyUL.html() + str);
}
}
});
🔶 function(result) 대신 function(list)를, page:page대신 rno:rno 파라미터로 수정.
get.jsp 일부
<div class="card-body">
<ul class="list-group chat">
</ul>
<button id="btnShowMore" class="btn btn-primary btn-block my-4">더보기</button>
<div class="reply-footer"></div>
</div>
🔶 첫 댓글부터 10개의 댓글이 보이고 그 밑에 더보기 버튼이 나오도록 버튼 생성.
get.jsp 일부
$(function() {
//btnShowMore 이벤트
$("#btnShowMore").click(function() {
// 마지막 rno 가져오기
var rno = $(".chat li:last").data("rno");
// showList() 호출
showList(rno);
});
});
🔶 더보기 버튼에 이벤트 걸기. (변수에 담는 게 왜 아직도 안 익숙할까;)
처음 불러 온 열 개의 댓글 다음 불러 올 댓글들은 마지막 댓글 번호(rno)의 다음 댓글 번호이다. 그래서 마지막 rno를 가져온 것.
get.jsp 일부
function showList(rno) {
replyService.getList({bno:bno, rno:rno}, function(list) {
// 댓글 목록 출력
console.log(list);
if(!list.length) {
$("#btnShowMore").prop("disabled", true).text("더이상 댓글이 없습니다.")
}
var str = "";
for(var i in list) {
str += '<li class="list-group-item" data-rno="' + list[i].rno + '">';
str += ' <div class="header">';
str += ' <strong>' + list[i].replyer + '</strong>';
str += ' <small class="float-right">' + replyService.displayTime(list[i].replyDate) + '</small>';
str += ' </div>';
str += ' <p class="mt-2">' + list[i].reply + '</p>';
str += '</li>';
}
replyUL.html(replyUL.html() + str);
})
}
🔶 더이상 불러올 댓글이 없을 때 if문으로 버튼 비활성화.
🔎 스크롤 바닥 감지를 통한 댓글 처리
get.jsp 일부
// 스크롤 바닥 감지
window.onscroll = function(e) {
console.log(e);
//추가되는 임시 콘텐츠
//window height + window scrollY 값이 document height보다 클 경우,
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// 마지막 rno 가져오기
var rno = $(".chat li:last").data("rno");
// showList() 호출
showList(rno);
}
};
🔶 더보기 버튼은 잠시 비활성화 해주고, 자바스크립트로 처리한다.
(무한 스크롤 로직은 블로그에서 검색!)
get.jsp 완성
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<jsp:include page="../includes/header.jsp"/>
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- Page Heading -->
<h1 class="h3 mb-2 text-gray-800">Tables</h1>
<p class="mb-4">DataTables is a third party plugin that is used to generate the demo table below.
For more information about DataTables, please visit the <a target="_blank"
href="https://datatables.net">official DataTables documentation</a>.</p>
<!-- DataTales Example -->
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary">Board view</h6>
</div>
<div class="card-body">
<form method="post" class="needs-validation" novalidate>
<div class="form-group">
<label for="bno" class="font-wieght-bold text-warning">bno</label>
<input type="text" class="form-control" id="bno" name="bno" required value="${board.bno}" readonly>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="form-group">
<label for="title" class="font-wieght-bold text-warning">title</label>
<input type="text" class="form-control" id="title" placeholder="게시글 제목 입력" name="title" required value="${board.title}" readonly>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="form-group">
<label for="content" class="font-wieght-bold text-warning">content</label>
<textarea class="form-control" rows=10 id="content" placeholder="게시글 내용 입력" name="content" required readonly>${board.content }</textarea>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="form-group">
<label for="writer" class="font-wieght-bold text-warning">writer</label>
<input type="text" class="form-control" id="writer" placeholder="게시글 작성자" name="writer" required value="${board.writer}" readonly>
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<a href="list${cri.listLink}" data-oper="list" class="btn btn-outline-info float-right">List</a>
<a href="modify${cri.listLink}&bno=${board.bno}" data-oper="modify" class="btn btn-outline-warning float-right mr-1">Modify</a>
</form>
</div>
</div>
<div class="card shadow mb-4">
<div class="card-header py-3">
<h6 class="m-0 font-weight-bold text-primary float-left"><i class="fa fa-comments fa-fw"></i> Reply</h6>
<button id="addReplyBtn" class="btn btn-sm btn-primary float-right">New Reply</button>
</div>
<div class="card-body">
<ul class="list-group chat">
<!-- <li class="list-group-item">
<div class="header">
<strong>user00</strong>
<small class="float-right">2021-04-12 12:37</small>
</div>
<p class="mt-2">댓글 본문 <br>댓글 본문 <br>댓글 본문</p>
</li> -->
</ul>
<!-- <button id="btnShowMore" class="btn btn-primary btn-block my-4">더보기</button> -->
<div class="reply-footer">
</div>
</div>
</div>
<!-- Result Modal-->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel"
aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="myModalLabel">REPLY MODAL</h5>
<button class="close" type="button" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form method="post" class="needs-validation" novalidate>
<div class="form-group">
<label for="reply" class="font-wieght-bold text-info">reply</label>
<input type="text" class="form-control" id="reply" name="reply" required placeholder="New Reply!">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="form-group">
<label for="replyer" class="font-wieght-bold text-info">replyer</label>
<input type="text" class="form-control" id="replyer" name="replyer" required placeholder="replyer!">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
<div class="form-group">
<label for="replyDate" class="font-wieght-bold text-info">replyDate</label>
<input type="text" class="form-control" id="replyDate" name="replyDate" required placeholder="2021-01-01 13:50">
<div class="valid-feedback">Valid.</div>
<div class="invalid-feedback">Please fill out this field.</div>
</div>
</form>
</div>
<div class="modal-footer">
<button id="modalModBtn" class="btn btn-warning btn-sm ac" type="button" data-dismiss="modal">Modify</button>
<button id="modalRemoveBtn" class="btn btn-danger btn-sm ac" type="button" data-dismiss="modal">Remove</button>
<button id="modalRegBtn" class="btn btn-primary btn-sm ac" type="button" data-dismiss="modal">Register</button>
<button id="modalCloseBtn" class="btn btn-secondary btn-sm" type="button" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<script>
// Disable form submissions if there are invalid fields
(function() {
'use strict';
window.addEventListener('load', function() {
// Get the forms we want to add validation styles to
var forms = document.getElementsByClassName('needs-validation');
// Loop over them and prevent submission
var validation = Array.prototype.filter.call(forms, function(form) {
form.addEventListener('submit', function(event) {
if (form.checkValidity() === false) {
event.preventDefault();
event.stopPropagation();
}
form.classList.add('was-validated');
}, false);
});
}, false);
})();
</script>
<script src="/resources/js/reply.js"></script>
<!-- /.container-fluid -->
<script>
var bno = <c:out value="${board.bno}"/>;
var replyUL = $(".chat");
var pageNum = 1;
showList(76); // 현재 163878 게시글의 댓글 다음 페이지
function showList(rno) {
replyService.getList({bno:bno, rno:rno}, function(list) {
// 댓글 목록 출력
console.log(list);
// 댓글 썼을 때 마지막 페이지 봐야 함.
//if(page == -1) showList(result.realEnd);
if(!list.length) {
$("#btnShowMore").prop("disabled", true).text("더이상 댓글이 없습니다.")
}
var str = "";
for(var i in list) {
str += '<li class="list-group-item" data-rno="' + list[i].rno + '">';
str += ' <div class="header">';
str += ' <strong>' + list[i].replyer + '</strong>';
str += ' <small class="float-right">' + replyService.displayTime(list[i].replyDate) + '</small>';
str += ' </div>';
str += ' <p class="mt-2">' + list[i].reply + '</p>';
str += '</li>';
}
replyUL.html(replyUL.html() + str);
// 댓글 페이징
/* str = '<ul class="pagination float-right mt-4">';
if(result.prev) {
str += '<li class="paginate_button page-item previous">';
str += ' <a class="page-link" href="' + (result.startPage - 1) + '">Prev</a>';
str += '</li>';
}
for(var i = result.startPage ; i <= result.endPage ; i++) {
var active = result.cri.pageNum == i ? "active" : "";
str += '<li class="paginate_button page-item ' + active + '">';
str += ' <a class="page-link" href="' + i + '">' + i + '</a>';
str += '</li>';
}
if(result.next) {
str += '<li class="paginate_button page-item next">';
str += ' <a class="page-link" href="' + (result.endPage + 1) + '">Next</a>';
str += '</li>';
}
str += '</ul>';
$(".reply-footer").html(str); */
})
}
$(function() {
// 등록폼 버튼 이벤트
$("#addReplyBtn").click(function() {
$("#myModal").find("input").val("");
$("#replyDate").closest("div").hide();
$(".ac").hide().eq(2).show();
$("#myModal").modal("show");
})
// 댓글목록 모달팝업 이벤트
$(".chat").on("click", "li", function() {
var rno = $(this).data("rno");
console.log(rno);
replyService.get(rno, function(result) {
console.log(result);
$("#reply").val(result.reply);
$("#replyer").val(result.replyer);
$("#replyDate").val(replyService.displayTime(result.replyDate)).prop("readonly", true).closest("div").show();
$("#myModal").data("rno", rno)
$(".ac").show().eq(2).hide();
$("#myModal").modal("show");
});
})
// 등록 적용버튼 이벤트
$("#modalRegBtn").click(function() {
var reply = {bno:bno, reply:$("#reply").val(), replyer:$("#replyer").val()};
replyService.add(reply, function(result) {
alert(result);
$("#myModal").modal("hide");
showList(-1);
});
});
// 수정 적용버튼 이벤트
$("#modalModBtn").click(function() {
var reply = {rno: $("#myModal").data("rno"), reply:$("#reply").val()};
replyService.update(reply, function(result) {
alert(result);
$("#myModal").modal("hide");
showList(pageNum);
});
});
// 삭제 적용버튼 이벤트
$("#modalRemoveBtn").click(function() {
replyService.remove($("#myModal").data("rno"), function(result) {
alert(result);
$("#myModal").modal("hide");
showList(pageNum);
});
});
// 댓글 페이지 버튼 이벤트
$(".reply-footer").on("click", "a", function() {
event.preventDefault();
pageNum = $(this).attr("href");
showList(pageNum);
});
//btnShowMore 이벤트
$("#btnShowMore").click(function() {
// 마지막 rno 가져오기
var rno = $(".chat li:last").data("rno");
// showList() 호출
showList(rno);
});
// 스크롤 바닥 감지
window.onscroll = function(e) {
console.log(e);
//추가되는 임시 콘텐츠
//window height + window scrollY 값이 document height보다 클 경우,
if((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
// 마지막 rno 가져오기
var rno = $(".chat li:last").data("rno");
// showList() 호출
showList(rno);
}
};
})
</script>
</div>
<!-- End of Main Content -->
<jsp:include page="../includes/footer.jsp"/>
'스프링 Spring' 카테고리의 다른 글
Part 6. 파일 업로드 처리 21. 04. 14. (0) | 2021.04.15 |
---|---|
Part 5. AOP와 트랜잭션 21. 04. 14. (0) | 2021.04.15 |
21. 04. 13. (0) | 2021.04.14 |
21. 04. 12. (0) | 2021.04.13 |
21. 04. 07. (0) | 2021.04.08 |