Day93 - [Jquery]댓글 수정, 삭제, 더보기

2021. 6. 29. 00:12Jquery

이번에는 저번에 댓글을 등록하고, 댓글을 화면에 뿌려주는 것 까지 비동기(실시간) 통신으로 완료했습니다.

 

이번에는, 등록된 댓글을 수정 및 삭제 그리고 댓글의 수가 많아지면 한번에 보여지는 댓글을 줄이고, 더보기 버튼을 누르면 추가적으로 댓글이 더 보이도록 해보겠습니다.

 

댓글의 수정과 삭제

제 프로젝트는 부트스트랩으로 만들어진 모달이 생성이 되어 있습니다.

 

생성되어 있는 모달의 코드는 아래와 같습니다.

<!-- 모달 ( 제이쿼리 modal("show") ) -->
	<div class="modal fade" id="replyModal" role="dialog">
		<div class="modal-dialog modal-md">
			<div class="modal-content">
				<div class="modal-header">
					<button type="button" class="btn btn-default pull-right" data-dismiss="modal">닫기</button>
					<h4 class="modal-title">댓글수정</h4>
				</div>
				<div class="modal-body">
					<!-- 수정폼 id값을 확인하세요-->
					<div class="reply-content">
					<textarea class="form-control" rows="4" id="modalReply" placeholder="내용입력"></textarea>
					<div class="reply-group">
						<div class="reply-input">
						    <input type="hidden" id="modalRno">
							<input type="password" class="form-control" placeholder="비밀번호" id="modalPw">
						</div>
						<button class="right btn btn-info" id="modalModBtn">수정하기</button>
						<button class="right btn btn-info" id="modalDelBtn">삭제하기</button>
					</div>
					</div>
					<!-- 수정폼끝 -->
				</div>
			</div>
		</div>
	</div>

댓글에 수정 또는 삭제를 누르면, 모달 창이 열리게 되는데, 이 때 수정 삭제 는 구분 없이 같이 나오도록 되어 있습니다.

 

이 부분을 아래처럼  만들어 줍니다.

$("#replyList").on("click", "a", function() {
            	event.preventDefault(); // 고유 이벤트 중지
            	
            	// 클릭한 대상의 번호를 모달창에 저장.
            	var rno = $(this).attr("href");
            	$("#modalRno").val(rno);
            	
            	// replyModify 라면 수정창, replyDelete 라면 삭제창의 형태로 사용
            	if( $(this).hasClass("replyModify") ){ // 수정창
            		
            		$(".modal-title").html("댓글수정");
            		$("#modalModBtn").css("display", "inline"); // 수정버튼은 보여지도록 처리
            		$("#modalDelBtn").css("display", "none"); // 삭제버튼은 숨겨지도록 처리
            		$("#modalReply").css("display", "inline"); // 수정창 보여지도록
            		
            	} else if ( $(this).hasClass("replyDelete") ) { // 삭제창
            		
            		$(".modal-title").html("댓글삭제");
            		$("#modalModBtn").css("display", "none"); // 수정버튼은 숨겨지도록 처리
            		$("#modalDelBtn").css("display", "inline"); // 삭제버튼은 보여지도록 처리
            		$("#modalReply").css("display", "none"); // 수정창 숨겨지도록
            		
            	}
            	
            	$("#replyModal").modal("show"); // 부트스트랩 모달 함수
            	
            }); // end on

여기서 on 함수를 사용한 이유는, 댓글을 화면에 뿌려주거나 추가하는 부분이 모두 비동기(ajax) 로 이루어져 있기 때문에 <a> 태그에 이벤트를 추가하는 부분이 실행하는 속도가 더 빠를 수 있기 때문입니다. ( on 함수는 이러한 문제를 해결함 )

 

수정 또는 삭제 를 눌렀을 때, 어떤 걸 눌렀는지 구분을 해줍니다.

$(this).hasClass()

 

각각의 상황에 맞추어서, 보여질 부분과 보여지지 말아야 할 부분을  설정 합니다.

 

댓글 수정

수정은 아래의 함수를 이용합니다.

// 수정 함수
$("#modalModBtn").click(function() {

  var rno = $("#modalRno").val();
  var reply = $("#modalReply").val();
  var replyPw = $("#modalPw").val();

  if(rno == '' || reply == '' || replyPw == ''){
    alert("내용, 비밀번호는 필수입니다");
    return;
  }

  $.ajax({
    type : "post",
    url : "../reply/update",
    contentType : "application/json; charset=UTF-8",
    data : JSON.stringify({"rno": rno, "reply": reply, "replyPw": replyPw}),
    success : function(data) {

    if(data == 1){ // 업데이트 성공
      $("#modalReply").val(""); // 내용비우기
      $("#modalPw").val("");
      $("#modalRno").val("");

      $("#replyModal").modal("hide"); // 모달창 내리기
      getList(); // 조회메서드 호출							
     } else {
      alert("비밀번호를 확인하세요");
      $("#modalPw").val("");
     }

    },
    error : function(status, error) {
    	alert("수정에 실패했습니다. 관리자에게 문의하세요");
    }
  });

});

모달창으로 들어와서 수정하기 버튼을 누르게 되면, 비동기 통신을 하는데 이 때, 필요한 변수들 ( 댓글번호, 내용, 비밀번호 ) 가 넘어가도록 합니다.

 

비동기 서버인 REST API ( 컨트롤러 ) 에서는, 댓글번호 와 비밀번호를 비교하는 메서드를 실행한 뒤, 비밀번호가 맞다면 수정하는 update 메서드를 실행 합니다.

Service , SerivceImpl , Mapper 부분에 알맞은 메서드를 추가한 후, Mapper.xml 은 아래와 같이 만들어 줍니다.

댓글 수정에 성공한다면, 매개변수로 넘긴, 댓글번호, 댓글내용, 비밀번호 등을 비워 줍니다.

댓글 수정에 실패한다면, 경고창을 띄운 후 비밀번호 만 비워 줍니다. ( 다시 입력할 수 있도록 )

 

이러한 과정들이 끝나면, 다시 한번 댓글을 화면에 뿌려줄 수 있도록 getList() 함수를 실행하도록 해줍니다.

 

댓글 삭제

댓글 삭제는 더욱 더 간단합니다.

 

삭제 버튼을 누르면 모달창이 나오도록 하고 ( 위에서 댓글 수정 부분과 같이 해결함 )

 

비밀번호를 입력한 후 삭제하기를 누르면, 컨트롤러 에서 댓글번호 와 비밀번호를 확인한 후, 댓글을 삭제 합니다.

마찬가지로 Service, ServiceImple, Mapper 부분에는 알맞은 메서드를 실행할 수 있도록 해주고, Mapper.xml 에는 아래와 같이 작성 합니다.

이렇게 완료가 되었다면 삭제 버튼이 있는 곳에서 비동기 통신을 해줘야 겠죠

// 삭제 함수
$("#modalDelBtn").click(function() {

  var rno = $("#modalRno").val();
  var replyPw = $("#modalPw").val();

  $.ajax({
    type : "post",
    url : "../reply/delete",
    contentType : "application/json; charset=UTF-8",
    data : JSON.stringify({"rno": rno, "replyPw": replyPw}),
    success : function(data) {

      if(data == 1){

        $("#modalRno").val("");
        $("#modalPw").val("");

        $("#replyModal").modal("hide");
        alert("삭제 완료");
        getList();

    	} else {
          alert("비밀번호를 확인하세요");
          $("#modalPw").val("");
        }
    },
    error : function(status, error){
    	alert("삭제에 실패했습니다. 관리자에게 문의하세요");
    }
  });

});

삭제 부분에서도 댓글번호, 댓글 비밀번호 가 매개변수로 넘어가도록 해주시고, 삭제를 완료하면 댓글번호, 댓글 비밀번호 를 비워주시고, 다시 댓글을 불러오도록 getList() 를 실행해 줍니다 ( 바로 반영되도록 )

 

더보기

더보기는, 댓글 수가 많을 때 더보기를 눌러서 아래로 댓글 수를 추가하는 건데요, 해당하는 부분을 페이지네이션으로 만들어도 되고, 이번에 하는 것처럼 더보기로 해도 됩니다.

 

데이터베이스에 들어가서, PL/SQL 문을 사용해서 댓글 수를 늘린 상태 입니다.

 

먼저, 더보기 버튼을 만들어 주세요

이제, 더보기 버튼을 눌렀을 때, 댓글을 추가적으로 불러올 수 있도록 해줄건데, 그러려면 먼저, 댓글을 일정부분만 가져올 수 있도록 해주어야 합니다.

 

댓글에도, pageNum ( 댓글페이지 ), amount ( 페이지당 보여질 댓글 수 ) 를 가지고 있어야 됩니다.

 

저번에 만든 Criteria 를 사용하도록 하겠습니다 ( search 는 사용 x )

이제, SQL 문을 생각해 봅시다.

 

기존에 전체 댓글을 가져오던 곳에서, ROWNUM 을 추가하고 인라인뷰 로 감싼다음에 바깥 쪽에서 WHERE 를 사용하면 됩니다.

그런데, 자세히 보면, 글번호 와 Criteria 를 같이 사용해야 되는데, 그냥 매개변수를 넘기게 되면 모호하다는 에러가 나타납니다.

 

여러가지 변수를 사용할 때는 해결방법이 3가지 있는데요

1. VO 에 모든 변수를 넣고 VO 1개만 넘긴다

2. Map 을 만들고 Map 에 필요한 매개변수들을 넘긴다

3. @Param 을 사용한다

 

이번에는 3번을 사용해서 아래와 같이 @Param 을 붙여주면 됩니다.

Service 쪽은 가만히 냅두고, Mapper 쪽 interface 만 위와 같이 수정해 주면 됩니다.

 

이렇게 하고, 컨트롤러 에서는 아래처럼 만들어 줍니다 ( getTotal 은 전체 댓글 수 입니다 )

이제 화면에서 더보기를 눌렀을 때, pageNum 을 1개씩 올려주기만 하면 되는데요, 댓글을 추가해주는 strAdd 와 댓글 페이지 넘버를 전역변수로 빼주어야 합니다.

 

var page = 1; // 페이지 번호
var strAdd = ""; // 댓글 목록 누적 변수

$("#moreList").click(function() {
	getList(++page, false); // 목록 호출
});

getList(1, true); // 데이터 조회 메서드 호출
// 데이터 조회
function getList(pageNum, reset) {

  var bno = "${boardVO.bno}"; // 게시글 번호

  // $.getJSON(요청주소, 콜백함수)
  $.getJSON("../reply/getList/" + bno + "/" + pageNum, function(data) {

    var total = data.total; // 전체게시글 수
    var data = data.list; // 목록

    // 페이지에 조건처리
    if(page * 20 >= total ) {
    	$("#moreList").css("display", "none"); // 더보기 버튼 처리
    } else {
    	$("#moreList").css("display", "block");
    }

    // reset이 true라면 strAdd를 공백으로 비우고 page = 1로 변경하고 다시 호출
    if(reset){
    	strAdd = "";
    	page = 1;
    }

    // 누적할 문자열을 만들고 innerHTML 형식으로 replyList 아래에 삽입
    for(var i = 0 ; i < data.length ; i++){

      strAdd += "<div class='reply-wrap'>";
      strAdd += "<div class='reply-image'>";
      strAdd += "<img src='../resources/img/profile.png'>";
      strAdd += "</div>";
      strAdd += "<div class='reply-content'>";
      strAdd += "<div class='reply-group'>";
      strAdd += "<strong class='left'>" + data[i].replyId + "</strong>";
      strAdd += "<small class='left'>" + data[i].timeGap + "</small>";

      // 클래스 이름이 버튼을 구별할 수 있는 이름 추가
      strAdd += "<a href='" + data[i].rno + "' class='right replyModify'><span class='glyphicon glyphicon-pencil'></span>수정</a>";
      strAdd += "<a href='" + data[i].rno + "' class='right replyDelete'><span class='glyphicon glyphicon-remove'></span>삭제</a>";
      strAdd += "</div>";
      strAdd += "<p class='clearfix'>" + data[i].reply + "</p>";
      strAdd += "</div>";
      strAdd += "</div>";
  }

  $("#replyList").html(strAdd); // 추가
  });
}

그리고 전체 댓글 수와 pageNum 을 비교해서 더보기 를 더 이상 누를 수 없도록 처리 해주면 됩니다.

 

여기까지 완성이 되었다면, 수정과 삭제 밑 전체 댓글 조회 하는 부분의 getList 를 각각 매개변수로 pageNum 을 넘길 수 있도록 해주는데, 이 때 수정과 삭제가 일어날 경우에는 reset 을 해서 댓글을 처음부터 보도록 strAdd 를 초기화 해주고, pageNum 을 1로 만듭니다.

 

간단하게 댓글 수정, 삭제, 더보기 를 만들어 보았습니다.