22.06.21 댓글 기능 끝 , .modal('show'/'hide')
getList( )해서 댓글 불러오는 for에
번호 전달하기 위해 a태그에 rno 넣고 클래스 이름 추가
<div class='reply-content'>
<div class='reply-group'>
<strong class='left'>` + replyList[i].replyId + `</strong>
<small class='left'>` + timeStamp(replyList[i].replyDate) + `</small>
<a href='` + replyList[i].rno + `' class='right replyDelete'>
<span class='glyphicon glyphicon-remove'></span>삭제</a>
<a href='` + replyList[i].rno + `' class='right replyModify'>
<span class='glyphicon glyphicon-pencil'></span>수정</a>
</div>
<p class='clearfix'>` + replyList[i].reply + `</p>
</div>
수정, 삭제 버튼 클릭시 이벤트 발생.
현 프로젝트에서는 getList()를 진행해서 목록을 불러오고
strAdd를 통해서 실제 태그가 아닌 html추가 형식으로 댓글들을 구현하고 있다.
strAdd안에서 작성되는 replyModify(수정버튼)에 일반 이벤트를 걸게되면 동작하지 않는다.
ajax함수의 실행이 더 늦게 완료가 되기 때문에, 실제 이벤트 선언이 먼저 실행되게 된다.
이런 상황에서는 화면에 댓글 관련 창은 아무것도 등록되어 있지 않은 형태이므로,
일반 클릭 이벤트가 동작하지 않는다.
이 때는, 이미 존재하는 #replyList에 이벤트를 등록하고, 이벤트를 자식에게 전파시켜
사용하는 제이쿼리의 이벤트 위임 함수를 반드시 사용해야 한다.
.on('이벤트' '이벤트발생태그' '함수') 이벤트를 이용
<script>
//수정,삭제
/*
$('.replyModify').click(function(e) {
e.preventDefault();
console.log('수정 이벤트 발생!');
}); 동작하지 않음
*/
$('#replyList').on('click', 'a', function(e) {
e.preventDefault(); //태그의 고유 기능을 중지.
//1. a태그가 두 개(수정, 삭제)이므로 버튼부터 확인.
//수정, 삭제가 발생하는 댓글 번호가 몇 번인지도 확인.
const rno = $(this).attr('href');
$('#modalRno').val(rno); //모달 내부에 숨겨진 input 태그에 댓글 번호를 담아서 전송.
//2. 모달 창 하나를 이용해서 상황에 따라 수정 / 삭제 모달을 구분하기 위해
//조건문 작성. (모달 하나로 수정, 삭제 같이 처리. 그러기 위해 디자인 조정)
//hasClass()는 클래스 이름에 매개값이 포함되어 있다면 true, 없다면 false.
if($(this).hasClass('replyModify')) {
//수정 버튼을 눌렀으므로 수정 모달 형식으로 꾸며주겠다.
$('.modal-title').html('댓글 수정');
$('#modalReply').css('display', 'inline');
$('#modalModBtn').css('display', 'inline');
$('#modalDelBtn').css('display', 'none'); //수정이므로 삭제버튼은 숨기자.
//jQuery를 이용한 모달 창 열기/닫기 .modal('show'/'hide')
//BootStrap에서는 trigger를 통해서 모달을 열고 닫았지만, 지금은 그런 게 없기 때문에
//제이쿼리를 이용하여 직접 모달을 열고 닫는다.
$('#replyModal').modal('show');
} else {
//삭제 버튼을 눌렀으므로 삭제 모달 형식으로 변경
$('.modal-title').html('댓글 삭제');
$('#modalReply').css('display', 'none');
$('#modalModBtn').css('display', 'none');
$('#modalDelBtn').css('display', 'inline');
$('#replyModal').modal('show');
}
}); //수정 or 삭제 버튼 클릭 이벤트 처리 끝.
</script>
클래스 이름에 매개값이 포함되어 있다면 true, 없다면 false.
jQuery를 이용한 모달 창 열기/닫기
모달창
<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>
<script>
//수정 처리 함수(수정 모달을 열어서 수정 내용을 작성 후 수정 버튼을 클릭했을 때)
$('#modalModBtn').click(function() {
const reply = $('#modalReply').val();
const rno = $('#modalRno').val();
const replyPw = $('#modalPw').val();
if(reply === '' || replyPw === '') {
alert('내용, 비밀번호를 확인하세요!');
return;
}
$.ajax({
type: 'post',
url: '<c:url value="/reply/update" />',
contentType: 'application/json',
data: JSON.stringify({
'reply': reply,
'rno': rno,
'replyPw': replyPw
}),
success: function(result) {
if(result === 'modSuccess') {
alert('정상 수정되었습니다.');
$('#modalReply').val('');
$('#modalPw').val('');
$('#replyModal').modal('hide');
//수정된 댓글 내용이 반영될 수 있도록 댓글 목록을 다시 불러 오기
getList(1, true);
} else {
alert('비밀번호를 확인하세요.');
$('#modalPw').val('');
$('#modalPw').focus();
}
},
error: function() {
alert('수정에 실패했습니다. 관리자에게 문의하세요!');
}
}); //end ajax(수정)
}); //수정 처리 이벤트 끝.
</script>
freeDetail.jsp에서 reply/update요청이 비동기 방식으로 들어온다.
pwCheck( ) 먼저 실행해서 비밀번호가 일치하는 경우 update진행.
<script>
//댓글 수정
@PostMapping("/update")
public String update(@RequestBody ReplyVO vo) {
//비밀번호 확인
int result = service.pwCheck(vo);
if(result == 1) { //비밀번호가 맞는 경우
service.update(vo);
return "modSuccess";
} else {
return "pwFail";
}
}
</script>
@Override
public int pwCheck(ReplyVO vo) {
return mapper.pwCheck(vo);
}
@Override
public void update(ReplyVO vo) {
mapper.update(vo);
}
댓글 번호 AND 비밀번호가 일치하는 수를 세어서 리턴.일치하면 1 아니면 0
<select id="pwCheck" resultType="int">
SELECT COUNT(*) FROM freereply
WHERE rno = #{rno} AND reply_pw = #{replyPw}
</select>
<update id="update">
UPDATE freereply
SET reply = #{reply}, update_date = sysdate
WHERE rno = #{rno}
</update>
<script>
//삭제 함수
$('#modalDelBtn').click(function() {
const rno = $('#modalRno').val();
const replyPw = $('#modalPw').val();
if(replyPw === '') {
alert('비밀번호를 확인하세요.');
return;
}
$.ajax({
type: 'post',
url: '<c:url value="/reply/delete" />',
data: JSON.stringify({
'rno': rno,
'replyPw': replyPw
}),
contentType: 'application/json',
success: function(data) {
if(data === 'delSuccess') {
alert('댓글이 삭제되었습니다.');
$('#modalPw').val('');//비밀번호 초기화
$('#replyModal').modal('hide');
getList(1, true);
} else {
alert('비밀번호가 틀렸습니다.');
$('#modalPw').val('');
$('#modalPw').focus();
}
},
error: function() {
alert('삭제에 실패했습니다. 관리자에게 문의하세요.');
}
}); //삭제 비동기 통신 끝.
}); //삭제 이벤트 끝.
</script>
freeDetail.jsp에서 reply/delete 요청이 비동기 방식으로 들어온다.
<script>
//댓글 삭제
@PostMapping("/delete")
public String delete(@RequestBody ReplyVO vo) {
int result = service.pwCheck(vo);
if(result == 1) {
service.delete(vo.getRno());
return "delSuccess";
} else {
return "pwFail";
}
}
</script>
@Override
public void delete(int rno) {
mapper.delete(rno);
}
<delete id="delete">
DELETE FROM freereply
WHERE rno = #{rno}
</delete>