[STS3] 댓글 기능(3)

1004다혜
|2024. 4. 23. 18:11

 

resources 폴더 안에 있는 js폴더에 reply.js 파일 생성 후 작성

/**
 * 
 */
 console.log("Reply");


var replyService = (function(){

	function add(reply, callback){
		console.log("reply......");
		
		$.ajax({
			type : "post",
			url : reply.contextPath + "/replies/new",
			data : JSON.stringify(reply),
			contentType : "application/json; charset=utf-8",
			success : function(result, status, xhr) {
				if (callback) {
					callback(result);
				}
			},
			error : function(xhr, status, er) {
				if (error) {
					error(er);
				}
			}
		})
	}
	
	return {
		add : add
	};
	
})();

 

read.jsp 파일에 js파일 연결 후 테스트 코드 작성

<script src="${ctx }/resources/js/reply.js"></script>
<script>
	$(function(){
		console.log(replyService);
		var bnoValue = "${board.bno}";
		
		replyService.add(
			{replytext: "js test1", replyer: "user01", bno: bnoValue, contextPath: "${ctx}"},
			function(result) {
				alert("result : " + result);
			}
		);
		
	});
</script>

 

톰캣 구동 후 상세페이지로 들어가서 alert 창이 잘 뜨는지 확인

 

DB에 잘 등록되었는지 확인

 

ReplyMapper.xml 하단의 getListWithPaging select문 수정

<select id="getListWithPaging" resultType="com.hanul.springstudent.domain.ReplyDTO">
    <![CDATA[
        SELECT	rno,
                bno,
                replytext,
                replyer,
                regdate,
                updatedate
        FROM	(SELECT /*+ INDEX(tbl_reply IDX_tbl_reply_PK) */
                    rownum rn,
                    rno,
                    bno,
                    replytext,
                    replyer,
                    regdate,
                    updatedate
                 FROM tbl_reply
                 WHERE bno = #{bno}
                 AND rno > 0
                 AND rownum <= #{cri.pageNum} * #{cri.amount})
        WHERE	rn > (#{cri.pageNum} - 1) * #{cri.amount}
    ]]>
</select>

 

ReplyMapper 클래스에 코드 추가

public int getCountByBno(int bno);

 

ReplyMapper.xml 하단의 getCountByBno select문 추가

<select id="getCountByBno" resultType="int">
    <![CDATA[
        SELECT	count(rno)
        FROM	tbl_reply
        WHERE	bno = #{bno}
    ]]>
</select>

 

domain 패키지에 ReplyPageDTO 생성 후 작성

@Data
@AllArgsConstructor
public class ReplyPageDTO {
	
	private int replyCnt;
	private List<ReplyDTO> list;
	
}

 

IReplyService 인터페이스에 추상메소드 추가

public ReplyPageDTO getListPage(Criteria cri, int bno);

 

ReplyServiceImpl 에서 추상메소드 구현

@Override
public ReplyPageDTO getListPage(Criteria cri, int bno) {

    return new ReplyPageDTO(
            mapper.getCountByBno(bno),
            mapper.getListWithPaging(cri, bno));
}

 

ReplyController 에 코드추가 후 상단에 있는 getList 메소드는 주석처리 

@GetMapping(value = "/pages/{bno}/{page}",
			produces = {MediaType.APPLICATION_JSON_UTF8_VALUE})
public ResponseEntity<ReplyPageDTO> getList(@PathVariable("page") int page, @PathVariable("bno") int bno) {
    Criteria cri = new Criteria(page, 10);
    log.info("get reply list bno : " + bno);
    log.info("cri : " + cri);

    return new ResponseEntity<>(service.getListPage(cri, bno), HttpStatus.OK);
}

 

reply.js 코드 작성

/**
 * 
 */
console.log("Reply Module........");

var replyService = (function() {
	function add(reply, callback, error) {
		console.log("add reply.................");
		
		$.ajax({
			type : "post",
			url : reply.contextPath + "/replies/new",
			data : JSON.stringify(reply),
			contentType : "application/json; charset=utf-8",
			success : function(result, status, xhr) {
				if (callback) {
					callback(result);
				}
			},
			error : function(xhr, status, er) {
				if (error) {
					error(er);
				}
			}
		})
	}
	
	// 댓글 목록
	function getList(param, callback, error) {
		var bno = param.bno;
		var page = param.page || 1;
		var contextPath = param.contextPath;

		$.getJSON(contextPath + "/replies/pages/" + bno + "/" + page,
			function(data) {
				if (callback) {
					callback(data.replyCnt, data.list);
				}
			}).fail(function(xhr, status, err) {
				if (error) {
					error();
				}
			});
	}
	
	// 댓글 삭제
	function remove(reply, callback, error) {
		$.ajax({
			type : "delete",
			url : reply.contextPath + "/replies/" + reply.rno,
			success : function(deleteResult, status, xhr) {
				if (callback) {
					callback(deleteResult);
				}
			},
			error : function(xhr, status, er) {
				if (error) {
					error(er);
				}
			}
		});
	}

	// 댓글 수정
	function update(reply, callback, error) {
		console.log("RNO: " + reply.rno);
		
		$.ajax({
			type : "put",
			url : reply.contextPath + "/replies/" + reply.rno,
			data : JSON.stringify(reply),
			contentType : "application/json; charset=utf-8",
			success : function(result, status, xhr) {
				if (callback) {
					callback(result);
				}
			},
			error : function(xhr, status, er) {
				if (error) {
					error(er);
				}
			}
		});
	}
	
	// 댓글 조회
	function get(reply, callback, error) {
		$.get(reply.contextPath + "/replies/" + reply.rno, function(result) {
			if (callback) {
				callback(result);
			}
		}).fail(function(xhr, status, err) {
			if (error) {
				error();
			}
		});
	}

	// 댓글 시간 처리
	function displayTime(timeValue) {

		var today = new Date();

		var gap = today.getTime() - timeValue;

		var dateObj = new Date(timeValue);
		var str = "";

		if (gap < (1000 * 60 * 60 * 24)) {
			var hh = dateObj.getHours();
			var mi = dateObj.getMinutes();
			var ss = dateObj.getSeconds();

			return [ (hh > 9 ? '' : '0') + hh, ':', (mi > 9 ? '' : '0') + mi,
					':', (ss > 9 ? '' : '0') + ss ].join('');
		} else {
			var yy = dateObj.getFullYear();
			var mm = dateObj.getMonth() + 1; // getMonth() is zero-based
			var dd = dateObj.getDate();

			return [ yy, '/', (mm > 9 ? '' : '0') + mm, '/',
					(dd > 9 ? '' : '0') + dd ].join('');
		}
	}

	return {
		add : add,
		get : get,
		getList : getList,
		remove : remove,
		update : update,
		displayTime : displayTime
	}
})();

 

read.jsp 파일에 댓글 목록과 등록/수정 모달 코드 추가

<!-- 댓글 목록 처리 -->
<div class="row">
    <div class="col-lg-12">
        <div class="panel panel-default">
            <div class="panel-heading">
                <i class="fa fa-comment fa-fw"></i>Reply
                <button id="addReplyBtn" class="btn btn-primary btn-xs pull-right">New Reply</button>
            </div>
            <div class="panel-body">
                <ul class="chat">
                </ul>
            </div>
            <div class="panel-footer">

            </div>
        </div>
    </div>
</div>

<!-- 신규 댓글 모달 -->
<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">REPLY MODAL</h4>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label>ReplyText</label>
                    <input class="form-control" name="replytext" value="New Reply!!!!">
                </div>
                <div class="form-group">
                    <label>Replyer</label>
                    <input class="form-control" name="replyer" value="replyer">
                </div>
                <div class="form-group">
                    <label>Reply Date</label>
                    <input class="form-control" name="replyDate" value="2024-01-01 13:13">
                </div>
            </div>
            <div class="modal-footer">
                <button id="modalModifyBtn" type="button" class="btn btn-warning">Modify</button>
                <button id="modalRemoveBtn" type="button" class="btn btn-danger">Remove</button>
                <button id="modalRegisterBtn" type="button" class="btn btn-primary">Register</button>
                <button id="modalCloseBtn" type="button" class="btn btn-default">Close</button>
            </div>          
        </div>
          <!-- /.modal-content -->
    </div>
<!-- /.modal-dialog -->
</div>
 <!-- /.modal -->

 

하단에 제이쿼리 추가

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

	var bnoValue = "${board.bno}";
	var replyUL = $(".chat");
	  
	showList(1);
	
	function showList(page) {
		console.log("show list " + page);
		   
		replyService.getList(
				{bno:bnoValue, contextPath:"${contextPath}", page: page || 1 }, 
				function(replyCnt, list) {
					console.log("replyCnt: "+ replyCnt );
					console.log("list: " + list);
					console.log(list);
					
					if(page == -1){
						pageNum = Math.ceil(replyCnt/10.0);
						showList(pageNum);
						return;
					}
					  
					var str="";
					 
					if(list == null || list.length == 0){
						return;
					}
					 
					for (var i = 0, len = list.length || 0; i < len; i++) {
						str +="<li class='left clearfix' data-rno='"+list[i].rno+"'>";
						str +="  <div><div class='header'><strong class='primary-font'>["
							+ list[i].rno+"] "+list[i].replyer+"</strong>";
						str +="    <small class='pull-right text-muted'>"
							+ replyService.displayTime(list[i].updatedate)+"</small></div>";
						str +="    <p>"+list[i].replytext+"</p></div></li>";
					}
					 
					replyUL.html(str);
					 
					showReplyPage(replyCnt);
		});//end function
	}//end showList
	
    var pageNum = 1;
    var replyPageFooter = $(".panel-footer");
    
    function showReplyPage(replyCnt) {
    	var endNum = Math.ceil(pageNum / 10.0) * 10;
    	var startNum = endNum - 9;
    	
    	var prev = startNum != 1;
    	var next = false;
    	
    	if(endNum * 10 >= replyCnt) {
    		endNum = Math.ceil(replyCnt/10.0);
    	}
    	
    	if(endNum * 10 < replyCnt) {
    		next = true;
    	}
    	
    	var str = "<ul class='pagination pull-right'>";
    	
    	if(prev) {
    		str+= "<li class='page-item'><a class='page-link' href='"+(startNum -1)+"'>Previous</a></li>";
    	}
    	
    	for(var i = startNum ; i <= endNum; i++) {
    		var active = pageNum == i? "active":"";
    		
    		str+= "<li class='page-item "+active+" '><a class='page-link' href='"+i+"'>"+i+"</a></li>";
    	}
    	
    	if(next) {
    		str+= "<li class='page-item'><a class='page-link' href='"+(endNum + 1)+"'>Next</a></li>";
    	}
    	
    	str += "</ul></div>";
    	
    	console.log(str);
    	
    	replyPageFooter.html(str);
    }
     
    replyPageFooter.on("click","li a", function(e) {
    	e.preventDefault();
    	console.log("page click");
    	
    	var targetPageNum = $(this).attr("href");
    	
    	console.log("targetPageNum: " + targetPageNum);
    	
    	pageNum = targetPageNum;
    	
    	showList(pageNum);
     });     
	
    var modal = $(".modal");
    var modalInputReplyText = modal.find("input[name='replytext']");
    var modalInputReplyer = modal.find("input[name='replyer']");
    var modalInputReplyDate = modal.find("input[name='replyDate']");
    
    var modalModifyBtn = $("#modalModifyBtn");
    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 = {
    			replytext: modalInputReplyText.val(),
    			replyer:modalInputReplyer.val(),
    			contextPath:"${contextPath}",
    			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 reply = {
    		rno : $(this).data("rno"),
    		contextPath:"${contextPath}",
    	};

    	replyService.get(reply, function(reply){
    		modalInputReplyText.val(reply.replytext);
    		modalInputReplyer.val(reply.replyer);
    		modalInputReplyDate.val(replyService.displayTime(reply.regdate)).attr("readonly","readonly");
    		modal.data("rno", reply.rno);
    		
    		modal.find("button[id !='modalCloseBtn']").hide();
    		modalModifyBtn.show();
    		modalRemoveBtn.show();
    		
    		$(".modal").modal("show");
    	});
    });
    
    modalModifyBtn.on("click", function(e){
    	var reply = {
    			rno:modal.data("rno"), 
    			replytext: modalInputReplyText.val(),
    			contextPath:"${contextPath}"
    		};
    	
    	replyService.update(reply, function(result) {
    		alert(result);
    		
     	    modal.modal("hide");
     	    showList(pageNum);
     	});
    });

    modalRemoveBtn.on("click", function (e) {
    	var reply = {
    			rno : modal.data("rno"), 
    			contextPath:"${contextPath}"
    		};
    	
    	replyService.remove(reply, function(result) {
    		alert(result);
    		
    		modal.modal("hide");
    		showList(pageNum);
    	});
    });
});
</script>

 

그리고 내 로컬호스트 상세페이지에 들어가서 댓글이 잘 뜨는지 확인

'Programming > Spring' 카테고리의 다른 글

[STS3] 댓글 기능(4)  (0) 2024.04.24
[STS3] 트랜잭션  (0) 2024.04.24
[STS3] 댓글 기능(2)  (0) 2024.04.22
[STS3] 댓글 기능(1)  (0) 2024.04.22
[STS3] 파일 업로드(1)  (0) 2024.04.22