웹 기초 31강 - 옵션(페이징 처리하기, 답글 달기)

Whatever·2021년 12월 9일
1

웹 기초

목록 보기
31/32

등록버튼을 눌렀을 때 해당 textarea를 찾아서 값을 가져오기
textarea.val()
방법1) this의 previous 형제를 찾기
방법2) this의 parent를 찾고 거기서 textarea 자식을 찾기

select reply_renum_seq.currval from dual => 현재 시퀀스의 번호 가져오기
from dual

한번에 vo객체를 가져오려면 (beanutil 사용)
BeanUtils.populate(vo, request.getParameterMap());

게시글 클릭시 - 그 글번호에 해당하는 댓글 리스트가 출력되어야 함

main.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <script src="../js/board.js"></script>
  
  
  <style>
  
  body{
  	margin: 10px;
  }
  .p1{
  	width: 80%;
  	padding: 5px;
  	margin: 3px;
  	float: left;
  }
  .p2{
  	width: 17%;
  	padding: 5px;
  	margin: 2px;
  	float: right;
  }
  
  .p3{
  	clear: both;
  	
  }
  input[name=reply]{
  height: 40px;
  vertical-align: top;
  }
  
  .pager{
    width: 100px;
    float: left;
    margin: 5px;
    margin-left: 5%;
  }
  </style>
<script type="text/javascript">
currentPage = 1;
reply = { } // 객체 선언 - 속성과 메서드를 동적으로 추가해서 사용 
$(function(){
	
	listPage(currentPage);
	
	//이벤트 	
	$('#list').on('click', '.action', function(){
	//또는 $(document).on('click', '.action', function(){})
		idx = $(this).attr('idx');
		name = $(this).attr('name');
		
		if(name=="modify"){
			alert(idx + "번째 글을 수정합니다");
		}else if(name=="delete"){
			alert(idx + "번째 글을 삭제합니다");
		}else if(name=="reply"){
			alert(idx + "번째 글에 댓글을 답니다");
			
			text = $(this).prev().val();
			console.log(text);
			
			// 숫자에 해당하는 대문자가 나옴
			name1 = String.fromCharCode(Math.random() * 26 + 65);
			name2 = String.fromCharCode(Math.random() * 26 + 97);
			name3 = parseInt(Math.random() * 100 + 1);
			
			// name, text
			reply.name = name1 + name2 + name3;
			reply.bonum = idx;
			reply.cont = text;
				
			// 서버로 전송 $.ajax({})
			replyInsert(this); // 댓글저장 - 등록버튼 객체
			 //insert에서는 안쓰고 list에서 씀
			//this객체가 insert에서는 필요없고 list에서 사용하기때문에 파라미터로 넘겨줌
			
			//댓글리스트 
			replyList();
			
			//비동기방식이라서 요청 - 응답의 순서가 아님
		}
		
	});
	
	//페이지번호 리스트 이벤트
	$('#pagelist').on('click', '.paging', function(){
		currentPage = $(this).text().trim();
		listPage(currentPage);
		
	});
	
	//next 이벤트
	$('#pagelist').on('click', '.next', function(){
		currentPage = parseInt($('.paging').last().text().trim()) + 1;
		listPage(currentPage);
	});
	
	//pre 이벤트
	$('#pagelist').on('click', '.prev', function(){
		currentPage = parseInt($('.paging').first().text().trim()) - 1;
		listPage(currentPage);
	});
	
	
});//$(function)
</script>
</head>
<body>
	<h2>게시판</h2>
	<br>
	<div id="list"></div>
	<div id="pagelist"></div>
</body>
</html>

board.js

/**
 * 
 */

function replyList(brep){
	//idx에 해당하는 댓글을 가져온다
	//리스트를 가져오는 ajax 수행
	$.ajax({
		url : '/board/ReplyList.do',
		type : 'get',
		data : {'bonum' : idx }, // reply는 댓글 저장 전에 생긴 것(생성되기 전) - idx대신 reply.bonum은 사용 못함
		success : function(res){
			//성공
			//댓글 리스트 출력
			rcode = '';
			$.each(res, function(i,v){ 
				
			rcode +='<div class="panel-body repl">                                                        ';
		    rcode +='<p class="p1">                                                                                ';
		    rcode +='<span class="wr">'+ v.name +'</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                  ';
		    rcode +='날짜 :<span class="wd">' + v.date + '</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;            ';
		    rcode +='</p>                                                                                          ';
		    rcode +='    	                                                                                      ';
		    rcode +='<p class="p2">                                                                                ';
		    rcode +='<input idx="'+ v.renum +'" type="button" name="r_modify" class="action" value="댓글수정">            ';
		    rcode +='<input idx="'+ v.renum +'" type="button" name="r_delete" class="action" value="댓글삭제">         ';
		    rcode +='</p>                                                                                          ';
		    rcode +='<p class="p3">                                                                                ';
		    rcode += v.cont;
		    rcode +='</p>   ';
		    rcode += '</div>';
		    
			});// $.each
			
			
			$(brep).parents('.panel').find('.pbody').append(rcode); //find - 밑으로 내려가면서 찾는 것(후손)
		    
		},
		error : function(xhr){
			alert("상태 : " + xhr.status);
		},
		dataType : 'json'
		
	});
	
	/**/
}

function replyInsert(brep){ // brep - 클릭한 button객체
	$.ajax({
		url : '/board/ReplyInsert.do',
		type : 'post',
		data : reply,
		success : function(res){
			//저장 성공 - res.sw
			//댓글 리스트 출력
			replyList(brep);
		},
		error : function(xhr){
			alert("상태 : " + xhr.status);
		},
		dataType : 'json'
	});
}

function listPage(cpage){
	
	
	
	$.ajax({
		url:"/board/List.do",
		data: { "page" : cpage},
		type: 'get',
		success: function(res){
			code = '<div class="panel-group" id="accordion">';
			$.each(res.datas ,function(i,v){
				code +='<div class="panel panel-default">';
			    code +='<div class="panel-heading">';
			    code +='<h4 class="panel-title">                                                                      ';
			    code +='<a data-toggle="collapse" data-parent="#accordion" href="#collapse'+ v.num +'">'+ v.subject +'</a>  ';
			    code +='</h4>                                                                                         ';
			    code +='</div>                                                                                        ';
			    code +='<div id="collapse'+ v.num +'" class="panel-collapse collapse">                                       ';
			    code +='<div class="panel-body pbody">                                                                      ';
			    code +='<p class="p1">                                                                                ';
			    code +='작성자 :<span class="wr">'+ v.writer +'</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                                      ';
			    code +='이메일 :<span class="em">'+ v.mail +'</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                           ';
			    code +='조회수 :<span class="hit">'+ v.hit +'</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                                        ';
			    code +='날짜 :<span class="wd">' + v.wdate + '</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;                                                ';
			    code +='</p>                                                                                          ';
			    code +='    	                                                                                      ';
			    code +='<p class="p2">                                                                                ';
			    code +='<input idx="'+ v.num +'" type="button" name="modify" class="action" value="수정">                                 ';
			    code +='<input idx="'+ v.num +'" type="button" name="delete" class="action" value="삭제">                                 ';
			    code +='</p>                                                                                          ';
			    code +='<p class="p3">                                                                                ';
			    code +='내용출력 내용출력<br>                                                                                 ';
			    code += v.content;
			    code +='</p>                                                                                          ';
			    code +='<p class="p4">                                                                                ';
			    code +='    		<textarea rows="" cols="100"></textarea>                                          ';
			    code +='    		<input idx="'+ v.num +'" type="button" value="등록" name="reply" class="action">                      ';
			    code +='    		                                                                                  ';
			    code +='    	</p>                                                                                  ';
				code +='	</div>                                                                                    ';
			    code +='  </div>                                                                                      ';
			    code +='</div>                                                                                        ';
			});
			code += '</div>';
			$('#list').html(code);
			
			$('#pagelist').empty();
			
			//이전버튼만들기
			if(res.sp > 1){
				pager = '<ul class="pager">';
				pager += '<li><a class="prev" href="#">Previous</a></li>';
				pager += '</ul>';
				
				$('#pagelist').append(pager);
			}
			
						
			/*<ul class="pager">
			<li><a href="#">Previous</a></li>
			<li><a href="#">Next</a></li>
			</ul>
			*/
			
			//페이지번호 만들기
			pager = '<ul class="pagination pager">';
			for(i=res.sp; i <=res.ep; i++){
				if(cpage == i){
					pager += '<li class="active"><a class="paging" href="#">' + i + '</a></li>';
				}else{
					pager += '<li><a class="paging" href="#">' + i + '</a></li>';
				}
			}
			pager += '</ul>';
			$('#pagelist').append(pager);
			
			
			//다음버튼 만들기
			if(res.ep < res.tp){
				pager = '<ul class="pager">';
				pager += '<li><a class="next" href="#">Next</a></li>';
				pager += '</ul>';
				
				$('#pagelist').append(pager);
			}
			
		},
		error: function(xhr){
			alert("상태 : " + xhr.status);
		},
		dataType: 'json'
	});
} //listPage

ReplyInsert.do

package kr.or.ddit.board.controller;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;

import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.board.vo.ReplyVO;

/**
 * Servlet implementation class ReplyInsert
 */
@WebServlet("/ReplyInsert.do")
public class ReplyInsert extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		
		//0. 클라이언트 요청 시 전송
		ReplyVO vo = new ReplyVO();
		
		try {
			BeanUtils.populate(vo, request.getParameterMap());
		} catch (IllegalAccessException | InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		vo.setBonum(Integer.parseInt(request.getParameter("bonum")));
		vo.setName(request.getParameter("name"));
		vo.setCont(request.getParameter("cont"));
		
		//1. service 객체 얻어오기
		IBoardService service = BoardServiceImpl.getInstance();
		
		//2. 
		int rnum = service.insertReply(vo);
		
		//3. 
		request.setAttribute("rnum", rnum);
		
		//
		request.getRequestDispatcher("board/result.jsp").forward(request, response);
		
	}

}

ReplyList.java

package kr.or.ddit.board.controller;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kr.or.ddit.board.service.BoardServiceImpl;
import kr.or.ddit.board.service.IBoardService;
import kr.or.ddit.board.vo.ReplyVO;

/**
 * Servlet implementation class ReplyList
 */
@WebServlet("/ReplyList.do")
public class ReplyList extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//0. 클라이언트 요청 시 전송 값 가져오기 : bonum
		int bonum = Integer.parseInt(request.getParameter("bonum"));
		
		//1. service객체
		IBoardService service = BoardServiceImpl.getInstance();
		
		//2. service메서드
		List<ReplyVO> list = service.listReply(bonum);
		

		//3.
		request.setAttribute("list", list);
		
		//4. 
		request.getRequestDispatcher("board/replyList.jsp").forward(request, response);
		
		
	}

}

replyList.jsp

<%@page import="kr.or.ddit.board.vo.ReplyVO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%
//서블릿에서 실행 결과 공유
List<ReplyVO> list = (List<ReplyVO>)request.getAttribute("list");

%>
[
<%
	for(int i = 0; i <list.size(); i++){
		ReplyVO vo = list.get(i);
		if(i > 0) out.print(",");
%>
	
	{
		"renum" : "<%= vo.getRenum() %>",
		"bonum" : "<%= vo.getBonum() %>",
		"name" : "<%= vo.getName() %>",
		"cont" : "<%= vo.getCont().replaceAll("\r", "").replaceAll("\n", "<br>") %>",
		"date" : "<%= vo.getRedate() %>"	
	}

<%
	}

%>

]

reply.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE sqlMap
	PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
	"http://ibatis.apache.org/dtd/sql-map-2.dtd">
	
<sqlMap namespace="reply">
	<insert id="insertReply" parameterClass="replyVO">
		insert into reply(renum, bonum, name, cont, redate) 
		values(
			reply_renum_seq.nextval,
			#bonum#,
			#name#,
			#cont#,
			sysdate
		)	
		
		<selectKey keyProperty="renum" resultClass="int">
			select reply_renum_seq.currval from dual		
		</selectKey>
	</insert>
	
	<select id="listReply" resultClass="replyVO" parameterClass="int">
		select * from reply where bonum = #bonum#
	</select>


</sqlMap>	

0개의 댓글