본문 바로가기

스프링 Spring

댓글 더보기 처리 이어서 21. 04. 14.

🔎 댓글 더보기 처리 이어서..

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