[B -2-46] Ajax 댓글 처리 19 : [특정 댓글의 클릭 이벤트 처리]

2019. 10. 9. 14:36Project B (SPMS)/Project B 파트5

반응형

views/board

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"%>

<%@ include file="../includes/header.jsp"%>
<div class="row">
	<div class="col-lg-12">
		<h1 class="page-header">게시판 조회</h1>
	</div>
	<!-- /.col-lg-12 -->
</div>
<!-- /.row -->
<div class="row">
	<div class="col-lg-12">
		<div class="panel panel-default">
			<div class="panel-heading">게시글 조회 페이지</div>
			<!-- /.panel-heading -->
			<div class="panel-body">
					<div class="form-group">
						<label>글 번호</label>
						<input class="form-control" name="bno" value='<c:out value="${board.bno }"/>' readonly="readonly">
					</div>
					<div class="form-group">
						<label>작성자</label>
						<input class="form-control" name="writer" value='<c:out value="${board.writer }"/>' readonly="readonly">
					</div>
					<div class="form-group">
						<label>제목</label>
						<input class="form-control" name="title" value='<c:out value="${board.title }"/>' readonly="readonly">
					</div>
					<div class="form-group">
						<label>내용</label>
						<textarea class="form-control" rows="10" name="content" readonly="readonly"><c:out value="${board.content}"/></textarea>
					</div>
					
					<button data-oper='modify' class="btn btn-default">수정</button>
					<button data-oper='list' class="btn btn-info">목록</button>
					
					<!-- operForm 시작 -->
					<form id='operForm' action="/board/modify" method="get">
						<input type='hidden' id='bno' name='bno' value='<c:out value="${board.bno}"/>'>
						<input type='hidden' name='pageNum' value='<c:out value="${cri.pageNum}"/>'>
						<input type='hidden' name='amount' value='<c:out value="${cri.amount}"/>'>
						
						<!-- Criteria의 키워드와 타입에 대한 처리 시작 -->
						<input type='hidden' name='keyword' value='<c:out value="${cri.keyword}"/>'>
						<input type='hidden' name='type' value='<c:out value="${cri.type}"/>'> 
						<!-- Criteria의 키워드와 타입에 대한 처리 종료 -->
					</form>
					<!-- operForm 종료 -->
			</div>
			<!-- /.panel-body -->
		</div>
		<!-- /.panel -->
	</div>
	<!-- /.col-lg-12 -->
</div>
<!-- /.row -->

<!-- 댓글 목록 표시 영역 시작 -->

<div class='row'>

  <div class="col-lg-12">

    <!-- /.panel -->
    <div class="panel panel-default">
      <div class="panel-heading">
        <i class="fa fa-comments fa-fw"></i> 댓글 목록
        <button id='addReplyBtn' class='btn btn-primary btn-xs pull-right'>댓글 작성</button>
      </div>
      
      <!-- /.panel-heading -->
      <div class="panel-body">
      
        <ul class="chat">

        </ul>
        <!-- ./ end ul -->
      </div>
      <!-- /.panel .chat-panel -->

	<div class="panel-footer"></div>


		</div>
  </div>
  <!-- ./ end row -->
</div>

<!-- 댓글 목록 표시 영역 끝 -->

</div>

<!-- 모달 추가 시작 -->
<!-- Modal -->
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
	<div class="modal-dialog">
		<div class="modal-content">
            <div class="modal-header">
				<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
              <h4 class="modal-title" id="myModalLabel">댓글 등록</h4>
            </div>
            <div class="modal-body">
            	<div class="form-group">
					<label>작성자</label> 
					<input class="form-control" name='replyer' value='replyer'>
				</div>
				<div class="form-group">
					<label>내용</label> 
					<input class="form-control" name='reply' value='New Reply!!!!'>
				</div>      
				<div class="form-group">
					<label>일자</label> 
					<input class="form-control" name='replyDate' value='2018-01-01 13:13'>
				</div>
            </div>
			<div class="modal-footer">
		        <button id='modalModBtn' type="button" class="btn btn-warning">수정</button>
		        <button id='modalRemoveBtn' type="button" class="btn btn-danger">삭제</button>
		        <button id='modalRegisterBtn' type="button" class="btn btn-primary">등록</button>
		        <button id='modalCloseBtn' type="button" class="btn btn-default">닫기</button>
			</div>          
		</div>
		<!-- /.modal-content -->
	</div>
	<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
<!-- 모달 추가 끝 -->

<script type="text/javascript">
$(document).ready(function() {

  var operForm = $("#operForm"); 

  $("button[data-oper='modify']").on("click", function(e){

    operForm.attr("action","/board/modify").submit();

  });

  $("button[data-oper='list']").on("click", function(e){

    operForm.find("#bno").remove();
    operForm.attr("action","/board/list")
    operForm.submit();

  });
});
</script>

<script type="text/javascript" src="/resources/js/reply.js"></script>

<!-- 이벤트 처리 시작 -->

<script>

$(document).ready(function () {
  
  var bnoValue = '<c:out value="${board.bno}"/>';
  var replyUL = $(".chat");
  
    showList(1);
    
	function showList(page){
	
		console.log("show list " + page);
    	replyService.getList({bno:bnoValue,page: page|| 1 }, function(list) {
    		
	    	console.log("list: " + list);
	    	var str="";
	
	    	if(list == null || list.length == 0){
	    		replyUL.html("");
	      		return;
	    	}
	
	    	for (var i = 0, len = list.length || 0; i < len; i++) {
	      		str += "<li class='left clearfix' data-rno='" + list[i].rno + "'>";
	      		str += "  <div>";
	      		str += "      <div class='header'>";
	      		str += "          <strong class='primary-font'>[" + list[i].rno + "] " + list[i].replyer + "</strong>"; 
	      		str += "          <small class='pull-right text-muted'>" + replyService.displayTime(list[i].replyDate) + "</small>";
	      		str += "      </div>";
	      		str += "      <p>" + list[i].reply + "</p>";
	      		str += "  </div>";
	      		str += "</li>";
	    	}
	
	    	replyUL.html(str);

		});//end function

	}//end showList

    var modal = $(".modal");
    var modalInputReply = modal.find("input[name='reply']");
    var modalInputReplyer = modal.find("input[name='replyer']");
    var modalInputReplyDate = modal.find("input[name='replyDate']");
    
    var modalModBtn = $("#modalModBtn");
    var modalRemoveBtn = $("#modalRemoveBtn");
    var modalRegisterBtn = $("#modalRegisterBtn");
    
    $("#modalCloseBtn").on("click", function(e){
    	
    	modal.modal('hide');
    });
    
    $("#addReplyBtn").on("click", function(e){
      
		modal.find("input").val("");
		modalInputReplyDate.closest("div").hide();
		modal.find("button[id !='modalCloseBtn']").hide();
		modalRegisterBtn.show();
      
		$(".modal").modal("show");
    });
    
	modalRegisterBtn.on("click",function(e){
		
		var reply = {
			reply: modalInputReply.val(),
			replyer:modalInputReplyer.val(),
			bno:bnoValue
		};
		
		replyService.add(reply, function(result){
          
			alert(result);
          
			modal.find("input").val("");
			modal.modal("hide");
          
			showList(1);
        });
    });
	
	//댓글 조회 클릭 이벤트 처리
    $(".chat").on("click", "li", function(e){
      
      var rno = $(this).data("rno");
      
      replyService.get(rno, function(reply){
      
        modalInputReply.val(reply.reply);
        modalInputReplyer.val(reply.replyer);
        modalInputReplyDate.val(replyService.displayTime(reply.replyDate)).attr("readonly","readonly");
        modal.data("rno", reply.rno);
        
        modal.find("button[id !='modalCloseBtn']").hide();
        modalModBtn.show();
        modalRemoveBtn.show();
        
        $(".modal").modal("show");
            
      });
    });
	
});

</script>

<!-- 이벤트 처리 끝 -->

<script>
	console.log("===============");
	console.log("JS TEST");
	
	var bnoValue = '<c:out value="${board.bno}"/>';
	/* 댓글 등록 처리 시작 */
	/* 
	// for replyService add test
	replyService.add(
    	{
    		reply:"JS Test", 
    		replyer:"tester", 
    		bno:bnoValue
    	},
	    function(result){
	      alert("RESULT : " + result);
	    }
	);
	 */
	/* 댓글 등록 처리 끝 */

	/* 댓글 목록 처리 시작 */
	/* 
	replyService.getList({bno:bnoValue, page:1}, function(list){
	  for(var i = 0, len = list.length||0; i < len; i++ ){
	    console.log(list[i]);
	  }
	});
	*/
	/* 댓글 목록 처리 끝 */
	
	/* 댓글 15 번 삭제 처리 시작 */
	/* 
	replyService.remove(15, function(count) {

		console.log(count);

		if (count === "success") {
			alert("REMOVED");
		}
	}, function(err) {
		alert('ERROR...');
	});
	 */
	/* 댓글 삭제 처리 끝 */
	
	/* 14번 댓글 수정 처리 시작 */
	/* 
	replyService.update({
		rno : 14,
		bno : bnoValue,
		reply : "댓글 수정 테스트 완료!"
	}, function(result) {
		alert("수정 완료...");
	});  
	 */
	/* 댓글 수정 처리 끝 */
	
	/* 16번 댓글 조회 처리 시작 */
	replyService.get(16, function(data){
		console.log('16번 댓글 조회 : ' + data); 
	});
	/* 댓글 조회 처리 끝 */
</script>

<!-- /#page-wrapper -->
<%@ include file="../includes/footer.jsp"%>

 

댓글은 댓글의 목록에서 내용이 전부 다 출력되기때문에 별도로 클릭한다는 것은 해당 댓글을 수정하거나 삭제하는 경우에만 발생한다.

 

댓글의 수정과 삭제는 원칙적으로 로그인한 사용자가 해당 댓글의 작성자인 경우에만 허락되어야 한다.

단, 현재까지 로그인에 대해서 처리된 적이 없으므로 코드에서는 어떠한 댓글도 수정/삭제가 되도록 작성한다.

 

DOM에서 이벤트 리스너를 등록하는 것은 반드시 해당 DOM 요소가 존재해야만 가능하다.

위와 같이 동적으로 Ajax를 통해서 <li> 태그들이 만들어지면 이후에 이벤트를 등록해야되기때문에 일반적인 방식이 아니라 이벤트 위임의 형태로 작성해야 한다.

 

이벤트 위임이란 실제로는 이벤트를 동적으로 생성되는 요소가 아닌 이미 존재하는 요소에 이벤트를 걸어주고, 나중에 이벤트의 대상을 변경해주는 방식이다.

 

제이쿼리on() 을 이용해서 간단히 처리가능하다.

 

댓글 리스트인 <ul> 태그의 클래스 chat을 이용해서 이벤트를 걸고 실제 이벤트 대상은 <li> 태그가 되도록 한다.

 

이 코드가 제대로 동작하게되면 화면에서는 댓글을 볼 수 있는 모달창을 처리해준다.

모달창을 브라우저에서 보여주는 코드는 특정한 댓글을 클릭 시 보여주도록 한다.

 

댓글을 조회하는 행위는 현재의 경우 모든 내용이 화면에 나오기때문에 별도로 조회할 필요는 없지만, 원칙적으로 Ajax로 댓글을 조회한 후 수정 및 삭제를 하는게 정상이다.

 

댓글을 갖고온 후에는 필요한 항목들을 채우고 수정삭제에 필요한 댓글 번호는 data-rno 속성을 만들어서 추가해놓는다.

 


특정 댓글의 클릭 이벤트 처리 결과 화면

 

 

특정 댓글을 클릭하면, 수정할 수 있게끔 해당 댓글에 대한 내용들을 가져와서 출력한다.

반응형