본문 바로가기
JSP

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(21) - ajax를 이용한 덧글 삭제 구현하기

by 김마리님 2020. 6. 15.

이전 게시글은 여기 >>

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(20) - ajax를 이용한 덧글 기능 구현하기

 

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(20) - ajax를 이용한 덧글 기능 구현하기

이전 게시글은 여기 Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(19) - 파일 업로드를 이용해 프로필 사진 넣기 > Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(18) - 키워드를 이용한 검색 �

itstudy-mary.tistory.com

 

이제 마지막이다. 덧글 삭제 기능만 만들면 된다.

덧글 삭제 버튼을 만들자.

 

-detail.jsp의 수정된 댓글 리스트 부분.

						<!-- 댓글 리스트 시작-->
						<ul id="reply__list" class="media-list">
						
							<c:forEach var="replyDto" items="${detailDto.replysDto }">
							<!-- 댓글 아이템 -->
							<li id="reply-${replyDto.reply.id }" class="media">	
								<img onerror="this.src='/blog/image/userProfile.png'" src="${replyDto.userProfile }" class="img-circle">		
								<div class="media-body">
									<strong class="text-primary">${replyDto.username }</strong>
									<p>
										${replyDto.reply.content }
									</p>
								</div>
								<div class="m-3">
									<c:if test="${replyDto.reply.userId eq sessionScope.principal.id }">
										<i onclick="replydelete(${replyDto.reply.id})" style="cursor : pointer;" class="Tiny material-icons">delete</i>
									</c:if>
								</div>
							</li>
							</c:forEach>
						</ul>
						<!-- 댓글 리스트 끝-->

보다시피, 덧글들을 출력하는 블록과 다른 블록으로 묶었다. 그럼으로써 inline-block 속성에 의해 휴지통 아이콘이 마지오른쪽 끝으로 밀려나게 된다. 그냥 두면 너무 붙어버리므로 m-3 속성을 부여한다.

이번에는 부트스트랩 말고 material을 이용해서 휴지통 아이콘을 구현할 것이다. 부트스트랩과 마찬가지로 material 역시 cdn을 요구한다.

https://materializecss.com/icons.html

 

Icons - Materialize

 

materializecss.com

 

cdn은 이전처럼 nav에 넣어서 통합하자.

 

-nav.jsp

<...>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>

<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">


<link href="https://cdn.jsdelivr.net/npm/summernote@0.8.18/dist/summernote.min.css" rel="stylesheet">
<...>

이 때 주의할 점은 이 아이콘은 반드시, 스타일 시트가 존재한다면 스타일 시트 위에 선언해야 한다.

 

태그에 material-icon 속성을 설정하고 내부에 맞는 아이콘에 맞는 명령어를 입력하면 해당 아이콘으로 바뀌어 출력된다. 

물론 이 태그는 문자 속성이기 때문에, 티를 내기 위해 커서도 바꾸어주었다.

이제 이 휴지통 아이콘이 클릭 되었을때 발생할 이벤트를 js로 짜보자.

 

-reply.js의 삭제 ajax

function replydelete(replyId){

		$.ajax({
			type: "post",
			url : "/blog/reply?cmd=deleteProc",
			data : "replyId="+replyId,
			contentType: "application/x-www-form-urlencoded; charset=utf-8",
			dataType: "text"
		}).done(function(result){
			if(result=="1"){
			alert("덧글 삭제 성공");
			var replyItem=$("#reply-"+replyId);
			replyItem.remove();
			}else{
				alert("덧글 삭제 실패");
			}
			

			
		}).fail(function(error){
			alert("덧글 삭제 실패");
			alert("replyId="+replyId);
			
		});
		
}

 

 

덧글 삭제에는 덧글의 고유번호만 알면 되니까, 이 덧글의 고유번호를 받아서 보낸다.

이 값 하나만 통신하면 되므로, 이번에는 json이 아니라 일반 key-value 형태로 통신해본다.

대신, 데이터 형태는 key-value 형태로 전송해줘야, 이걸 받은 액션이 Parameter로 받을 수 있다.

 

이제 이 ajax로 온 데이터를 처리해줄 액션을 만들어보자.

 

- ReplyController의 router부분

	public Action router(String cmd) {
		if(cmd.equals("writeProc")) {
			//덧글 작성 프로세스
			return new ReplyWriteProcAction(); 
		}else if(cmd.equals("deleteProc")) {
			// 덧글 삭제 프로세스
			return new ReplyDeleteProcAction();
		}
		return null;
		
	}

 

이제 라우터에서 호출할 액션을 만들어준다.

 

- ReplyDeleteProcAction.java

package com.cos.blog.action.reply;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cos.blog.action.Action;
import com.cos.blog.repository.ReplyRepository;
import com.cos.blog.util.Script;

public class ReplyDeleteProcAction implements Action{
@Override
public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	System.out.println("ReplyDeleteProcAction : replyId : "+request.getParameter("replyId"));
	
	if(request.getParameter("replyId")==null||request.getParameter("replyId").equals("")) {
		return;
	}
	int replyId=Integer.parseInt(request.getParameter("replyId"));
	ReplyRepository replyRepository=ReplyRepository.getInstance();
	int result=replyRepository.deleteByID(replyId);
	Script.outText(result+"", response);
}
}

ajax에서 key-value로 받아온 값을 parameter로 받고, 이 값이 통신으로 왔기 때문에 String으로 왔다. 이걸 다시 int로 파싱해서 데이터베이스에 삭제 쿼리에 접근한다.

 

-ReplyRepository.java의 삭제 쿼리 부분

	public int deleteByID(int id) {
		final String SQL="delete from reply where id = ?";
		try {
			conn=DBConn.getConnection();
			pstmt = conn.prepareStatement(SQL);
			//물음표 완성하기
			pstmt.setInt(1, id);
			
			return pstmt.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(TAG+"deleteByID : "+e.getMessage());
		}finally {
			DBConn.close(conn, pstmt);
		}
		
		return -1;
	}

이제 ajax에서는 이 결과가 1이면 받은 덧글의 div id를 맞춰보고, 같은 div id를 가지고 있는 div를 완전히 삭제 해버린다.

 

 

 

- 자바스크립트의 remove와 empty의 차이

remove의 경우 자신을 포함, 모든 요소를 지워버린다. 즉, div를 삭제하면 div 틀까지 모두 삭제해버리지만.

empty의 경우 자신 하위의 요소만 삭제한다, 즉 div를 삭제해도 div 틀은 남은 상태로 하위요소(내용물)만 삭제된다.

 

 

반응형