Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 다형성
- 제네릭
- Java
- 컬렉션프레임워크
- EnhancedFor
- 사용자예외클래스생성
- cursor문
- 객체 비교
- 참조형변수
- 환경설정
- 어윈 사용법
- 예외처리
- 컬렉션 타입
- 오라클
- exception
- GRANT VIEW
- 정수형타입
- 인터페이스
- 자동차수리시스템
- 메소드오버로딩
- 대덕인재개발원
- 생성자오버로드
- 예외미루기
- oracle
- 자바
- NestedFor
- 집합_SET
- abstract
- 한국건설관리시스템
- 추상메서드
Archives
- Today
- Total
거니의 velog
231011_AJAX 강의 본문
[board.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
<script src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="<%= request.getContextPath() %>/js/script.js"></script>
<script>
var mypath = "<%= request.getContextPath() %>";
var currentpage = 1;
$(function(){
// 실행하자마자 리스트 출력 - stype, sword 없다.
$.listBoardServer(currentpage);
// 페이지 번호 클릭 이벤트
$(document).on("click", ".pageno", function(){
currentpage = parseInt( $(this).text().trim() );
$.listBoardServer(currentpage);
})
// 다음 클릭 이벤트
$(document).on("click", "#next", function(){
currentpage = parseInt( $(".pageno").last().text().trim() ) + 1;
$.listBoardServer(currentpage);
});
// 이전 클릭 이벤트
$(document).on("click", "#prev", function(){
currentpage = parseInt( $(".pageno").first().text().trim() ) - 1;
$.listBoardServer(currentpage);
});
// Search 검색 이벤트
$(document).on("click", "#search", function(){
currentpage = 1;
$.listBoardServer(currentpage);
});
});
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype" name="stype" style="margin-right: 5px;">
<option value="">전체</option>
<option value="writer">작성자</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select>
<input class="form-control me-2" id="sword" name="sword" type="text" placeholder="Search">
<button id="search" class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br /><br />
<div id="result"></div>
<br />
<br />
<div id="pageList"></div>
</body>
</html>
[style07.css]
@charset "utf-8";
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100;300;500;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: "Noto Sans KR", sans-serif!important;
color: #333;
word-break: keep-all;
}
a {
text-decoration: none;
color: #333;
}
.cen {
max-width: 1000px;
width: 100%;
margin: auto;
}
/***********************************/
.card-body {
display: flex;
flex-direction: column;
}
.divContBox {
display: flex;
flex-direction: row;
}
.divCont1 {
flex: 70%;
}
.divCont2 {
flex: 30%;
text-align: right;
}
header {
padding: 4%;
height: 200px;
border: 2px dotted gold;
margin: 30px;
background-image: linear-gradient(to bottom, cornflowerBlue, white);
}
section {
padding: 3%;
margin: 30px;
}
.dlog {
border: 1px dotted blue;
padding: 10px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.dlog input {
width: calc(150px - 1%);
height: 30px;
}
iframe[name=iboard] {
width: 100%;
height: 500px;
border: none;
}
.navbar { margin : 2% }
.navbar a {
display: none;!important
/* visibility: hidden!important; */
}
.card-body div {
border: 1px solid gold;
margin : 5px;
padding : 5px;
}
#pageList {
position: relative;
}
#pageList .pagination {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
[script.js]
$.listBoardServer = function(cpage){
var stype = $("#stype option:selected").val().trim();
var sword = $("#sword").val().trim();
//console.log("stype : " + stype);
//console.log("sword : " + sword);
// 실행하자마자 리스트 출력
$.ajax({
url : `${mypath}/boardList.do`,
type : 'post',
data : {
'page' : cpage,
'stype' : stype,
'sword' : sword
},
success : function(res){
var code = "<div class='container mt-3'>";
code += "<div id='accordion'>";
$.each(res.data, function(i, v){
code += `<div class="card">
<div class="card-header">
<a class="btn" data-bs-toggle="collapse" href="#collapse${v.num}">
${v.subject}
</a>
</div>
<div id="collapse${v.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.writer}</span>
이메일 <span class="em">${v.mail}</span>
조회수 <span class="fit">${v.hit}</span>
날짜 <span class="date">${v.wdate}</span>
</div>
<div class="divCont2">
<button idx="${v.num}" class="modifyCont btn btn-warning btn-sm" type="button">수정</button>
<button idx="${v.num}" class="removeCont btn btn-danger btn-sm" type="button">삭제</button>
</div>
</div>
<div>${v.content}</div>
<div>댓글쓰기 textarea 등록버튼</div>
</div>
</div>
</div>`;
}); // 반복문 끝
code += "</div>";
code += "</div>";
$("#result").html(code);
// 페이지 번호 만들기
var paging = pageList(res.startPage, res.endPage, res.totalPage);
// 출력
$("#pageList").html(paging);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
} // 리스트 끝
var pageList = function(sp, ep, tp){
var paging = `<ul class="pagination">`;
// 이전
if(sp > 1){
paging += `<li class="page-item"><a id="prev" class="page-link" href="#">Previous</a></li>`;
}
// 페이지 번호
for(var i=sp; i<=ep; i++){
if(i == currentpage){
paging += `<li class="page-item active"><a class="page-link pageno" href="#">${i}</a></li>`;
}else{
paging += `<li class="page-item"><a class="page-link pageno" href="#">${i}</a></li>`;
}
}
// 다음
if(ep < tp){
paging += `<li class="page-item"><a id="next" class="page-link" href="#">Next</a></li>`;
}
paging += `</ul>`;
return paging;
}
[index.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>로그인 화면</title>
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
</head>
<body>
<header>
<div class="dlog">
<!--
로그인 / 로그아웃 - HttpSession을 이용하여 로그인폼 또는 로그아웃폼을 삽입.
logpro.jsp를 실행시킨 결과물을 현재 페이지에 삽입
-->
<jsp:include page="logpro.jsp"></jsp:include>
</div>
<br />
<a href="join.jsp" target="iboard">회원가입</a>
<a href="../board/board.jsp" target="iboard">게시판</a>
</header>
<section>
<iframe name="iboard" src="../board/board.jsp"></iframe>
</section>
</body>
</html>
- http://localhost/boardpro/member/index.jsp
[reply.xml]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="reply">
<!-- 댓글 삭제 결과 : int, param : 댓글번호(int), id이름 = 메소드 이름 -->
<delete id="deleteReply" parameterType="int">
DELETE FROM replytab
WHERE renum = #{renum}
</delete>
<!-- 댓글 수정 결과 : int, param : vo, id이름 = 메소드 이름 -->
<update id="updateReply" parameterType="replyVo">
UPDATE replytab SET cont = #{cont}, redate = sysdate
WHERE renum = #{renum} AND bonum = #{bonum}
</update>
<!-- 댓글 저장 결과 : int, param : vo, id이름 = 메소드 이름 -->
<insert id="insertReply" parameterType="replyVo">
INSERT INTO replytab (renum, bonum, name, cont, redate)
VALUES (replytab_renum_seq.nextval, #{bonum}, #{name}, #{cont}, sysdate)
</insert>
<!-- 댓글 리스트 결과 : vo, param : 게시판번호(int), id이름 = 메소드 이름 -->
<select id="listReply" parameterType="int" resultType="replyVo">
select * from replytab
where bonum = #{bonum}
</select>
</mapper>
[ReplyDaoImpl.java]
package kr.or.ddit.reply.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import kr.or.ddit.mybatis.config.MyBatisUtil;
import kr.or.ddit.reply.vo.ReplyVO;
public class ReplyDaoImpl implements IReplyDAO {
private static ReplyDaoImpl dao;
private ReplyDaoImpl() {}
public static ReplyDaoImpl getInstance() {
if(dao == null) dao = new ReplyDaoImpl();
return dao;
}
@Override
public int insertReply(ReplyVO vo) {
SqlSession session = MyBatisUtil.getSqlSession();
int cnt = 0;
try {
cnt = session.insert("reply.insertReply", vo);
if(cnt > 0) session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session != null) session.close();
}
return cnt;
}
@Override
public int deleteReply(int rno) {
SqlSession session = MyBatisUtil.getSqlSession();
int cnt = 0;
try {
cnt = session.delete("reply.deleteReply", rno);
if(cnt > 0) session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session != null) session.close();
}
return cnt;
}
@Override
public int updateReply(ReplyVO vo) {
SqlSession session = MyBatisUtil.getSqlSession();
int cnt = 0;
try {
cnt = session.update("reply.updateReply", vo);
if(cnt > 0) session.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session != null) session.close();
}
return cnt;
}
@Override
public List<ReplyVO> listReply(int bno) {
SqlSession session = MyBatisUtil.getSqlSession();
List<ReplyVO> replyList = null;
try {
replyList = session.selectList("reply.listReply", bno);
} catch (Exception e) {
e.printStackTrace();
} finally {
if(session != null) session.close();
}
return replyList;
}
}
[ReplyServiceImpl.java]
package kr.or.ddit.reply.service;
import java.util.List;
import kr.or.ddit.reply.dao.IReplyDAO;
import kr.or.ddit.reply.dao.ReplyDaoImpl;
import kr.or.ddit.reply.vo.ReplyVO;
public class ReplyServiceImpl implements IReplyService {
private IReplyDAO dao;
private static ReplyServiceImpl service;
private ReplyServiceImpl() {
dao = ReplyDaoImpl.getInstance();
}
public static ReplyServiceImpl getInstance() {
if(service == null) service = new ReplyServiceImpl();
return service;
}
@Override
public int insertReply(ReplyVO vo) {
return dao.insertReply(vo);
}
@Override
public int deleteReply(int rno) {
return dao.deleteReply(rno);
}
@Override
public int updateReply(ReplyVO vo) {
return dao.updateReply(vo);
}
@Override
public List<ReplyVO> listReply(int bno) {
return dao.listReply(bno);
}
}
[ReplyVO.java]
package kr.or.ddit.reply.vo;
public class ReplyVO {
private int renum;
private int bonum;
private String name;
private String cont;
private String redate;
public ReplyVO() {}
public ReplyVO(int renum, int bonum, String name, String cont, String redate) {
this.renum = renum;
this.bonum = bonum;
this.name = name;
this.cont = cont;
this.redate = redate;
}
public int getRenum() {
return renum;
}
public void setRenum(int renum) {
this.renum = renum;
}
public int getBonum() {
return bonum;
}
public void setBonum(int bonum) {
this.bonum = bonum;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCont() {
return cont;
}
public void setCont(String cont) {
this.cont = cont;
}
public String getRedate() {
return redate;
}
public void setRedate(String redate) {
this.redate = redate;
}
@Override
public String toString() {
return "ReplyVO [renum=" + renum + ", bonum=" + bonum + ", name=" + name + ", cont=" + cont + ", redate="
+ redate + "]";
}
}
[ReplyInsert.java]
package kr.or.ddit.reply.controller;
import java.io.IOException;
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.reply.service.IReplyService;
import kr.or.ddit.reply.service.ReplyServiceImpl;
import kr.or.ddit.reply.vo.ReplyVO;
@WebServlet("/replyInsert.do")
public class ReplyInsert extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 전송데이터 받기
//data : reply ==> name, bonum, cont
int bonum = Integer.parseInt(request.getParameter("bonum"));
String name = request.getParameter("name");
String cont = request.getParameter("cont");
ReplyVO rvo = new ReplyVO();
rvo.setBonum(bonum);
rvo.setName(name);
rvo.setCont(cont);
// 서비스 객체 얻기
IReplyService service = ReplyServiceImpl.getInstance();
// 서비스 메소드 호출 - 결과값 int
int insRepCnt = service.insertReply(rvo);
// 결과를 request에 저장
request.setAttribute("insRepCnt", insRepCnt);
// view페이지 설정 = forward
request.getRequestDispatcher("/boardview/insRepResult.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
[insRepResult.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 서블릿에서 저장한 데이터 꺼내기
int insRepCnt = (int) request.getAttribute("insRepCnt");
if(insRepCnt > 0){
%>
{
"msg" : "댓글 저장 성공"
}
<%}else{%>
{
"msg" : "댓글 저장 실패"
}
<%
}
%>
[board.jsp]
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
<script src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="<%= request.getContextPath() %>/js/script.js"></script>
<%
// 로그인 상태 체크
MemberVO mvo = (MemberVO) session.getAttribute("loginok");
String jsonVo = null;
Gson gson = new Gson();
if(mvo != null) jsonVo = gson.toJson(mvo);
/*
jsonVo = {
"mem_id" : "a001",
"mem_pass" : "asdfasdf",
"mem_name" : "김은대"
}
*/
%>
<script>
var mvo = <%= jsonVo %>; /* mvo.mem_id, mvo.mem_pass, mvo.mem_name */
//console.log(mvo);
var mypath = "<%= request.getContextPath() %>";
var currentpage = 1;
var reply = {}; // 객체형 변수, 동적으로 추가 가능. - reply.bonum, reply.name, reply.cont
$(function(){
// 실행하자마자 리스트 출력 - stype, sword 없다.
$.listBoardServer(currentpage);
// 페이지 번호 클릭 이벤트
$(document).on("click", ".pageno", function(){
currentpage = parseInt( $(this).text().trim() );
$.listBoardServer(currentpage);
})
// 다음 클릭 이벤트
$(document).on("click", "#next", function(){
currentpage = parseInt( $(".pageno").last().text().trim() ) + 1;
$.listBoardServer(currentpage);
});
// 이전 클릭 이벤트
$(document).on("click", "#prev", function(){
currentpage = parseInt( $(".pageno").first().text().trim() ) - 1;
$.listBoardServer(currentpage);
});
// Search 검색 이벤트
$(document).on("click", "#search", function(){
currentpage = 1;
$.listBoardServer(currentpage);
});
// 게시글 수정, 게시글 삭제, 댓글 등록, 제목 클릭, 댓글 삭제, 댓글 수정 이벤트
$(document).on("click", ".action", function(){
var thisIs = $(this);
var name = thisIs.attr("name");
var idx = thisIs.attr("idx");
if(name == "delete"){
//alert(idx + "번 글을 삭제합니다.");
}else if(name == "title"){
//alert(idx + "번 글의 댓글을 출력합니다.");
}else if(name == "modify"){
//alert(idx + "번 글을 수정합니다.");
}else if(name == "reply"){
//alert(idx + "번 댓글을 등록합니다.");
//입력한 내용 가져오기
var cont = thisIs.prev().val();
//console.log(cont);
reply.name = mvo.mem_name;
reply.bonum = idx;
reply.cont = cont;
//console.log(reply);
$.replyInsert();
// 입력 값 비우기
thisIs.prev().val("");
}
});
});
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype" name="stype" style="margin-right: 5px;">
<option value="">전체</option>
<option value="writer">작성자</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select>
<input class="form-control me-2" id="sword" name="sword" type="text" placeholder="Search">
<button id="search" class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br /><br />
<div id="result"></div>
<br />
<br />
<div id="pageList"></div>
</body>
</html>
[script.js]
$.replyInsert = function(){
$.ajax({
url : `${mypath}/replyInsert.do`,
type : 'post',
data : reply, /* name, bonum, cont */
success : function(res){
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
$.listBoardServer = function(cpage){
var stype = $("#stype option:selected").val().trim();
var sword = $("#sword").val().trim();
//console.log("stype : " + stype);
//console.log("sword : " + sword);
// 실행하자마자 리스트 출력
$.ajax({
url : `${mypath}/boardList.do`,
type : 'post',
data : {
'page' : cpage,
'stype' : stype,
'sword' : sword
},
success : function(res){
var code = "<div class='container mt-3'>";
code += "<div id='accordion'>";
$.each(res.data, function(i, v){
code += `<div class="card">
<div class="card-header">
<a class="btn action" name="title" idx="${v.num}" data-bs-toggle="collapse" href="#collapse${v.num}">
${v.subject}
</a>
</div>
<div id="collapse${v.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.writer}</span>
이메일 <span class="em">${v.mail}</span>
조회수 <span class="fit">${v.hit}</span>
날짜 <span class="date">${v.wdate}</span>
</div>
<div class="divCont2">
<button idx="${v.num}" class="action btn btn-warning btn-sm" type="button" name="modify">수정</button>
<button idx="${v.num}" class="action btn btn-danger btn-sm" type="button" name="delete">삭제</button>
</div>
</div>
<div>${v.content}</div>
<div>
<textarea rows="2" cols="50"></textarea>
<button style="height: 50px; vertical-align: top; padding: 0px 10px;" class="action" name="reply" type="button" idx="${v.num}">등록</button>
</div>
</div>
</div>
</div>`;
}); // 반복문 끝
code += "</div>";
code += "</div>";
$("#result").html(code);
// 페이지 번호 만들기
var paging = pageList(res.startPage, res.endPage, res.totalPage);
// 출력
$("#pageList").html(paging);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
} // 리스트 끝
var pageList = function(sp, ep, tp){
var paging = `<ul class="pagination">`;
// 이전
if(sp > 1){
paging += `<li class="page-item"><a id="prev" class="page-link" href="javascript:void(0)">Previous</a></li>`;
}
// 페이지 번호
for(var i=sp; i<=ep; i++){
if(i == currentpage){
paging += `<li class="page-item active"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}else{
paging += `<li class="page-item"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}
}
// 다음
if(ep < tp){
paging += `<li class="page-item"><a id="next" class="page-link" href="javascript:void(0)">Next</a></li>`;
}
paging += `</ul>`;
return paging;
}
- http://localhost/boardpro/member/index.jsp
[ReplyList.java]
package kr.or.ddit.reply.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.reply.service.IReplyService;
import kr.or.ddit.reply.service.ReplyServiceImpl;
import kr.or.ddit.reply.vo.ReplyVO;
@WebServlet("/replyList.do")
public class ReplyList extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 전송 데이터 가져오기
int bonum = Integer.parseInt(request.getParameter("bonum"));
// 서비스 객체
IReplyService service = ReplyServiceImpl.getInstance();
// 메소드 호출
List<ReplyVO> repList = service.listReply(bonum);
// 저장
request.setAttribute("repList", repList);
// 보내기
request.getRequestDispatcher("/boardview/listRepResult.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
[listRepResult.jsp]
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.reply.vo.ReplyVO"%>
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 서블릿에서 저장한 데이터 꺼내기
List<ReplyVO> repList = (List<ReplyVO>) request.getAttribute("repList");
Gson gson = new Gson();
String result = gson.toJson(repList);
out.print(result);
out.flush();
%>
[board.jsp]
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
<script src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="<%= request.getContextPath() %>/js/script.js"></script>
<%
// 로그인 상태 체크
MemberVO mvo = (MemberVO) session.getAttribute("loginok");
String jsonVo = null;
Gson gson = new Gson();
if(mvo != null) jsonVo = gson.toJson(mvo);
/*
jsonVo = {
"mem_id" : "a001",
"mem_pass" : "asdfasdf",
"mem_name" : "김은대"
}
*/
%>
<script>
var mvo = <%= jsonVo %>; /* mvo.mem_id, mvo.mem_pass, mvo.mem_name */
//console.log(mvo);
var mypath = "<%= request.getContextPath() %>";
var currentpage = 1;
var reply = {}; // 객체형 변수, 동적으로 추가 가능. - reply.bonum, reply.name, reply.cont
var idx = ""; // idx 전역변수 선언
var target = ""; // .action의 this 전역변수
$(function(){
// 실행하자마자 리스트 출력 - stype, sword 없다.
$.listBoardServer(currentpage);
// 페이지 번호 클릭 이벤트
$(document).on("click", ".pageno", function(){
currentpage = parseInt( $(this).text().trim() );
$.listBoardServer(currentpage);
})
// 다음 클릭 이벤트
$(document).on("click", "#next", function(){
currentpage = parseInt( $(".pageno").last().text().trim() ) + 1;
$.listBoardServer(currentpage);
});
// 이전 클릭 이벤트
$(document).on("click", "#prev", function(){
currentpage = parseInt( $(".pageno").first().text().trim() ) - 1;
$.listBoardServer(currentpage);
});
// Search 검색 이벤트
$(document).on("click", "#search", function(){
currentpage = 1;
$.listBoardServer(currentpage);
});
// 게시글 수정, 게시글 삭제, 댓글 등록, 제목 클릭, 댓글 삭제, 댓글 수정 이벤트
$(document).on("click", ".action", function(){
var thisIs = $(this);
target = thisIs;
var name = thisIs.attr("name");
idx = thisIs.attr("idx");
if(name == "delete"){
//alert(idx + "번 글을 삭제합니다.");
}else if(name == "title"){
//alert(idx + "번 글의 댓글을 출력합니다.");
// 댓글 출력 ajax 수행
$.replyList();
}else if(name == "modify"){
//alert(idx + "번 글을 수정합니다.");
}else if(name == "reply"){
//alert(idx + "번 댓글을 등록합니다.");
//입력한 내용 가져오기
var cont = thisIs.prev().val();
//console.log(cont);
reply.name = mvo.mem_name;
reply.bonum = idx;
reply.cont = cont;
//console.log(reply);
// 댓글 입력 ajax 수행
$.replyInsert();
// 입력 값 비우기
thisIs.prev().val("");
}
});
});
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype" name="stype" style="margin-right: 5px;">
<option value="">전체</option>
<option value="writer">작성자</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select>
<input class="form-control me-2" id="sword" name="sword" type="text" placeholder="Search">
<button id="search" class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br /><br />
<div id="result"></div>
<br />
<br />
<div id="pageList"></div>
</body>
</html>
[script.js]
$.replyList = function(){
$.ajax({
url : `${mypath}/replyList.do`,
type : 'post',
data : { "bonum" : idx },
success : function(res){
//console.log(res);
var recode = "";
$.each(res, function(i, v){
var cont = v.cont;
cont = cont.replaceAll(/\n/g, "<br />");
recode += `<div class="reply-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.name}</span>
날짜 <span class="date">${v.redate}</span>
</div>
<div class="divCont2">
<button idx="${v.renum}" class="action btn btn-warning btn-sm" type="button" name="rep_modify">댓글수정</button>
<button idx="${v.renum}" class="action btn btn-danger btn-sm" type="button" name="rep_delete">댓글삭제</button>
</div>
</div>
<div>${cont}</div>
</div>`;
});
// 댓글 출력
//target.parent().next().find(".card-body").append(recode);
//target.parents(".card").find(".reply-body").empty();
target.parents(".card").find(".reply-body").remove();
target.parents(".card").find(".card-body").append(recode);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
$.replyInsert = function(){
$.ajax({
url : `${mypath}/replyInsert.do`,
type : 'post',
data : reply, /* name, bonum, cont */
success : function(res){
//console.log(res);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
$.listBoardServer = function(cpage){
var stype = $("#stype option:selected").val().trim();
var sword = $("#sword").val().trim();
//console.log("stype : " + stype);
//console.log("sword : " + sword);
// 실행하자마자 리스트 출력
$.ajax({
url : `${mypath}/boardList.do`,
type : 'post',
data : {
'page' : cpage,
'stype' : stype,
'sword' : sword
},
success : function(res){
var code = "<div class='container mt-3'>";
code += "<div id='accordion'>";
$.each(res.data, function(i, v){
code += `<div class="card">
<div class="card-header">
<a class="btn action" name="title" idx="${v.num}" data-bs-toggle="collapse" href="#collapse${v.num}">
${v.subject}
</a>
</div>
<div id="collapse${v.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.writer}</span>
이메일 <span class="em">${v.mail}</span>
조회수 <span class="fit">${v.hit}</span>
날짜 <span class="date">${v.wdate}</span>
</div>
<div class="divCont2">
<button idx="${v.num}" class="action btn btn-warning btn-sm" type="button" name="modify">수정</button>
<button idx="${v.num}" class="action btn btn-danger btn-sm" type="button" name="delete">삭제</button>
</div>
</div>
<div>${v.content}</div>
<div>
<textarea rows="2" cols="50"></textarea>
<button style="height: 50px; vertical-align: top; padding: 0px 10px;" class="action" name="reply" type="button" idx="${v.num}">등록</button>
</div>
</div>
</div>
</div>`;
}); // 반복문 끝
code += "</div>";
code += "</div>";
$("#result").html(code);
// 페이지 번호 만들기
var paging = pageList(res.startPage, res.endPage, res.totalPage);
// 출력
$("#pageList").html(paging);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
} // 리스트 끝
var pageList = function(sp, ep, tp){
var paging = `<ul class="pagination">`;
// 이전
if(sp > 1){
paging += `<li class="page-item"><a id="prev" class="page-link" href="javascript:void(0)">Previous</a></li>`;
}
// 페이지 번호
for(var i=sp; i<=ep; i++){
if(i == currentpage){
paging += `<li class="page-item active"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}else{
paging += `<li class="page-item"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}
}
// 다음
if(ep < tp){
paging += `<li class="page-item"><a id="next" class="page-link" href="javascript:void(0)">Next</a></li>`;
}
paging += `</ul>`;
return paging;
}
- http://localhost/boardpro/member/index.jsp
[reply.xml]
<!-- 댓글 리스트 결과 : vo, param : 게시판번호(int), id이름 = 메소드 이름 -->
<select id="listReply" parameterType="int" resultType="replyVo">
select * from replytab
where bonum = #{bonum}
order by renum desc
</select>
[board.jsp]
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
<script src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="<%= request.getContextPath() %>/js/script.js"></script>
<%
// 로그인 상태 체크
MemberVO mvo = (MemberVO) session.getAttribute("loginok");
String jsonVo = null;
Gson gson = new Gson();
if(mvo != null) jsonVo = gson.toJson(mvo);
/*
jsonVo = {
"mem_id" : "a001",
"mem_pass" : "asdfasdf",
"mem_name" : "김은대"
}
*/
%>
<script>
var mvo = <%= jsonVo %>; /* mvo.mem_id, mvo.mem_pass, mvo.mem_name */
//console.log(mvo);
var mypath = "<%= request.getContextPath() %>";
var currentpage = 1;
var reply = {}; // 객체형 변수, 동적으로 추가 가능. - reply.bonum, reply.name, reply.cont
var idx = ""; // idx 전역변수 선언
var target = ""; // .action의 this 전역변수
$(function(){
// 실행하자마자 리스트 출력 - stype, sword 없다.
$.listBoardServer(currentpage);
// 페이지 번호 클릭 이벤트
$(document).on("click", ".pageno", function(){
currentpage = parseInt( $(this).text().trim() );
$.listBoardServer(currentpage);
})
// 다음 클릭 이벤트
$(document).on("click", "#next", function(){
currentpage = parseInt( $(".pageno").last().text().trim() ) + 1;
$.listBoardServer(currentpage);
});
// 이전 클릭 이벤트
$(document).on("click", "#prev", function(){
currentpage = parseInt( $(".pageno").first().text().trim() ) - 1;
$.listBoardServer(currentpage);
});
// Search 검색 이벤트
$(document).on("click", "#search", function(){
currentpage = 1;
$.listBoardServer(currentpage);
});
// 게시글 수정, 게시글 삭제, 댓글 등록, 제목 클릭, 댓글 삭제, 댓글 수정 이벤트
$(document).on("click", ".action", function(){
var thisIs = $(this);
target = thisIs;
var name = thisIs.attr("name");
idx = thisIs.attr("idx");
if(name == "delete"){
//alert(idx + "번 글을 삭제합니다.");
}else if(name == "title"){
//alert(idx + "번 글의 댓글을 출력합니다.");
// 댓글 출력 ajax 수행
$.replyList();
}else if(name == "modify"){
//alert(idx + "번 글을 수정합니다.");
}else if(name == "reply"){
//alert(idx + "번 댓글을 등록합니다.");
//입력한 내용 가져오기
var cont = thisIs.prev().val();
//console.log(cont);
reply.name = mvo.mem_name;
reply.bonum = idx;
reply.cont = cont;
//console.log(reply);
// 댓글 입력 ajax 수행
$.replyInsert();
// 댓글을 화면에 추가
// $.replyInsert(); ==> success에서 수행
// 입력 값 비우기
thisIs.prev().val("");
}
});
});
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype" name="stype" style="margin-right: 5px;">
<option value="">전체</option>
<option value="writer">작성자</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select>
<input class="form-control me-2" id="sword" name="sword" type="text" placeholder="Search">
<button id="search" class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br /><br />
<div id="result"></div>
<br />
<br />
<div id="pageList"></div>
</body>
</html>
[script.js]
// 댓글 리스트 가져오기
$.replyList = function(){
$.ajax({
url : `${mypath}/replyList.do`,
type : 'post',
data : { "bonum" : idx },
success : function(res){
//console.log(res);
var recode = "";
$.each(res, function(i, v){
var cont = v.cont;
cont = cont.replaceAll(/\n/g, "<br />");
recode += `<div class="reply-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.name}</span>
날짜 <span class="date">${v.redate}</span>
</div>
<div class="divCont2">
<button idx="${v.renum}" class="action btn btn-warning btn-sm" type="button" name="rep_modify">댓글수정</button>
<button idx="${v.renum}" class="action btn btn-danger btn-sm" type="button" name="rep_delete">댓글삭제</button>
</div>
</div>
<div>${cont}</div>
</div>`;
});
// 댓글 출력
//target.parent().next().find(".card-body").append(recode);
//target.parents(".card").find(".reply-body").empty();
target.parents(".card").find(".reply-body").remove();
target.parents(".card").find(".card-body").append(recode);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
// 댓글 저장
$.replyInsert = function(){
$.ajax({
url : `${mypath}/replyInsert.do`,
type : 'post',
data : reply, /* name, bonum, cont */
success : function(res){
//console.log(res);
// 댓글을 화면에 추가하기 위해서
// 댓글 리스트 가져오기를 수행한다.
$.replyList();
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
$.listBoardServer = function(cpage){
var stype = $("#stype option:selected").val().trim();
var sword = $("#sword").val().trim();
//console.log("stype : " + stype);
//console.log("sword : " + sword);
// 실행하자마자 리스트 출력
$.ajax({
url : `${mypath}/boardList.do`,
type : 'post',
data : {
'page' : cpage,
'stype' : stype,
'sword' : sword
},
success : function(res){
var code = "<div class='container mt-3'>";
code += "<div id='accordion'>";
$.each(res.data, function(i, v){
code += `<div class="card">
<div class="card-header">
<a class="btn action" name="title" idx="${v.num}" data-bs-toggle="collapse" href="#collapse${v.num}">
${v.subject}
</a>
</div>
<div id="collapse${v.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.writer}</span>
이메일 <span class="em">${v.mail}</span>
조회수 <span class="fit">${v.hit}</span>
날짜 <span class="date">${v.wdate}</span>
</div>
<div class="divCont2">
<button idx="${v.num}" class="action btn btn-warning btn-sm" type="button" name="modify">수정</button>
<button idx="${v.num}" class="action btn btn-danger btn-sm" type="button" name="delete">삭제</button>
</div>
</div>
<div>${v.content}</div>
<div>
<textarea rows="2" cols="50"></textarea>
<button style="height: 50px; vertical-align: top; padding: 0px 10px;" class="action" name="reply" type="button" idx="${v.num}">등록</button>
</div>
</div>
</div>
</div>`;
}); // 반복문 끝
code += "</div>";
code += "</div>";
$("#result").html(code);
// 페이지 번호 만들기
var paging = pageList(res.startPage, res.endPage, res.totalPage);
// 출력
$("#pageList").html(paging);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
} // 리스트 끝
var pageList = function(sp, ep, tp){
var paging = `<ul class="pagination">`;
// 이전
if(sp > 1){
paging += `<li class="page-item"><a id="prev" class="page-link" href="javascript:void(0)">Previous</a></li>`;
}
// 페이지 번호
for(var i=sp; i<=ep; i++){
if(i == currentpage){
paging += `<li class="page-item active"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}else{
paging += `<li class="page-item"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}
}
// 다음
if(ep < tp){
paging += `<li class="page-item"><a id="next" class="page-link" href="javascript:void(0)">Next</a></li>`;
}
paging += `</ul>`;
return paging;
}
- http://localhost/boardpro/member/index.jsp
[ReplyDelete.java]
package kr.or.ddit.reply.controller;
import java.io.IOException;
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.reply.service.IReplyService;
import kr.or.ddit.reply.service.ReplyServiceImpl;
@WebServlet("/replyDelete.do")
public class ReplyDelete extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("utf-8");
// 전송 데이터 받기 - renum
int renum = Integer.parseInt(request.getParameter("renum"));
// service객체
IReplyService service = ReplyServiceImpl.getInstance();
// service 메소드 호출 - int 결과
int delRepCnt = service.deleteReply(renum);
// 결과를 request에 저장
request.setAttribute("delRepCnt", delRepCnt);
// view 페이지 설정 - forward
request.getRequestDispatcher("/boardview/delRepResult.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
[delRepResult.jsp]
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
// 서블릿에서 저장한 데이터 꺼내기
int delRepCnt = (int) request.getAttribute("delRepCnt");
if(delRepCnt > 0){
%>
{
"msg" : "댓글 삭제 성공"
}
<%}else{%>
{
"msg" : "댓글 삭제 실패"
}
<%
}
%>
[board.jsp]
<%@page import="com.google.gson.Gson"%>
<%@page import="kr.or.ddit.member.vo.MemberVO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="true" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>게시판 리스트</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="<%= request.getContextPath() %>/css/style07.css" rel="stylesheet" />
<script src="<%= request.getContextPath() %>/js/jquery-3.7.1.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/js/bootstrap.bundle.min.js"></script>
<script defer src="<%= request.getContextPath() %>/js/script.js"></script>
<%
// 로그인 상태 체크
MemberVO mvo = (MemberVO) session.getAttribute("loginok");
String jsonVo = null;
Gson gson = new Gson();
if(mvo != null) jsonVo = gson.toJson(mvo);
/*
jsonVo = {
"mem_id" : "a001",
"mem_pass" : "asdfasdf",
"mem_name" : "김은대"
}
*/
%>
<script>
var mvo = <%= jsonVo %>; /* mvo.mem_id, mvo.mem_pass, mvo.mem_name */
//console.log(mvo);
var mypath = "<%= request.getContextPath() %>";
var currentpage = 1;
var reply = {}; // 객체형 변수, 동적으로 추가 가능. - reply.bonum, reply.name, reply.cont
var idx = ""; // idx 전역변수 선언
var reidx = ""; // reidx 전역변수 선언
var target = ""; // .action의 this 전역변수
$(function(){
// 실행하자마자 리스트 출력 - stype, sword 없다.
$.listBoardServer(currentpage);
// 페이지 번호 클릭 이벤트
$(document).on("click", ".pageno", function(){
currentpage = parseInt( $(this).text().trim() );
$.listBoardServer(currentpage);
})
// 다음 클릭 이벤트
$(document).on("click", "#next", function(){
currentpage = parseInt( $(".pageno").last().text().trim() ) + 1;
$.listBoardServer(currentpage);
});
// 이전 클릭 이벤트
$(document).on("click", "#prev", function(){
currentpage = parseInt( $(".pageno").first().text().trim() ) - 1;
$.listBoardServer(currentpage);
});
// Search 검색 이벤트
$(document).on("click", "#search", function(){
currentpage = 1;
$.listBoardServer(currentpage);
});
// 게시글 수정, 게시글 삭제, 댓글 등록, 제목 클릭, 댓글 삭제, 댓글 수정 이벤트
$(document).on("click", ".action", function(){
var thisIs = $(this);
target = thisIs;
var name = thisIs.attr("name");
idx = thisIs.attr("idx");
reidx = thisIs.attr("reidx");
if(name == "delete"){
//alert(idx + "번 글을 삭제합니다.");
}else if(name == "title"){
//alert(idx + "번 글의 댓글을 출력합니다.");
// 댓글 출력 ajax 수행
$.replyList();
}else if(name == "modify"){
//alert(idx + "번 글을 수정합니다.");
}else if(name == "reply"){
//alert(idx + "번 댓글을 등록합니다.");
//입력한 내용 가져오기
var cont = thisIs.prev().val();
//console.log(cont);
reply.name = mvo.mem_name;
reply.bonum = idx;
reply.cont = cont;
//console.log(reply);
// 댓글 입력 ajax 수행
$.replyInsert();
// 댓글을 화면에 추가
// $.replyInsert(); ==> success에서 수행
// 입력 값 비우기
thisIs.prev().val("");
}else if(name == "rep_modify"){
//alert(reidx + "번 댓글을 수정합니다.");
}else if(name == "rep_delete"){
//alert(reidx + "번 댓글을 삭제합니다.");
// ajax수행 - 댓글 삭제
$.replyRemove();
}
});
});
</script>
</head>
<body>
<nav class="navbar navbar-expand-sm navbar-dark bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="javascript:void(0)">Logo</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#mynavbar">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="mynavbar">
<ul class="navbar-nav me-auto">
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="javascript:void(0)">Link</a>
</li>
</ul>
<form class="d-flex">
<select class="form-select" id="stype" name="stype" style="margin-right: 5px;">
<option value="">전체</option>
<option value="writer">작성자</option>
<option value="subject">제목</option>
<option value="content">내용</option>
</select>
<input class="form-control me-2" id="sword" name="sword" type="text" placeholder="Search">
<button id="search" class="btn btn-primary" type="button">Search</button>
</form>
</div>
</div>
</nav>
<br /><br />
<div id="result"></div>
<br />
<br />
<div id="pageList"></div>
</body>
</html>
[script.js]
// 댓글 삭제
$.replyRemove = function(){
$.ajax({
url : `${mypath}/replyDelete.do`,
type : 'post',
data : { "renum" : reidx },
success : function(res){
//console.log(res);
// DB 삭제 성공 했으면 화면에서 삭제
target.parents(".reply-body").remove();
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
// 댓글 리스트 가져오기
$.replyList = function(){
$.ajax({
url : `${mypath}/replyList.do`,
type : 'post',
data : { "bonum" : idx },
success : function(res){
//console.log(res);
var recode = "";
$.each(res, function(i, v){
var cont = v.cont;
cont = cont.replaceAll(/\n/g, "<br />");
recode += `<div class="reply-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.name}</span>
날짜 <span class="date">${v.redate}</span>
</div>
<div class="divCont2">
<button reidx="${v.renum}" class="action btn btn-warning btn-sm" type="button" name="rep_modify">댓글수정</button>
<button reidx="${v.renum}" class="action btn btn-danger btn-sm" type="button" name="rep_delete">댓글삭제</button>
</div>
</div>
<div>${cont}</div>
</div>`;
});
// 댓글 출력
//target.parent().next().find(".card-body").append(recode);
//target.parents(".card").find(".reply-body").empty();
target.parents(".card").find(".reply-body").remove();
target.parents(".card").find(".card-body").append(recode);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
// 댓글 저장
$.replyInsert = function(){
$.ajax({
url : `${mypath}/replyInsert.do`,
type : 'post',
data : reply, /* name, bonum, cont */
success : function(res){
//console.log(res);
// 댓글을 화면에 추가하기 위해서
// 댓글 리스트 가져오기를 수행한다.
$.replyList();
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
}
$.listBoardServer = function(cpage){
var stype = $("#stype option:selected").val().trim();
var sword = $("#sword").val().trim();
//console.log("stype : " + stype);
//console.log("sword : " + sword);
// 실행하자마자 리스트 출력
$.ajax({
url : `${mypath}/boardList.do`,
type : 'post',
data : {
'page' : cpage,
'stype' : stype,
'sword' : sword
},
success : function(res){
var code = "<div class='container mt-3'>";
code += "<div id='accordion'>";
$.each(res.data, function(i, v){
code += `<div class="card">
<div class="card-header">
<a class="btn action" name="title" idx="${v.num}" data-bs-toggle="collapse" href="#collapse${v.num}">
${v.subject}
</a>
</div>
<div id="collapse${v.num}" class="collapse" data-bs-parent="#accordion">
<div class="card-body">
<div class="divContBox">
<div class="divCont1">
작성자 <span class="wr">${v.writer}</span>
이메일 <span class="em">${v.mail}</span>
조회수 <span class="fit">${v.hit}</span>
날짜 <span class="date">${v.wdate}</span>
</div>
<div class="divCont2">
<button idx="${v.num}" class="action btn btn-warning btn-sm" type="button" name="modify">수정</button>
<button idx="${v.num}" class="action btn btn-danger btn-sm" type="button" name="delete">삭제</button>
</div>
</div>
<div>${v.content}</div>
<div>
<textarea rows="2" cols="50"></textarea>
<button style="height: 50px; vertical-align: top; padding: 0px 10px;" class="action" name="reply" type="button" idx="${v.num}">등록</button>
</div>
</div>
</div>
</div>`;
}); // 반복문 끝
code += "</div>";
code += "</div>";
$("#result").html(code);
// 페이지 번호 만들기
var paging = pageList(res.startPage, res.endPage, res.totalPage);
// 출력
$("#pageList").html(paging);
},
error : function(xhr){
alert("상태 : " + xhr.status);
},
dataType : 'json'
});
} // 리스트 끝
var pageList = function(sp, ep, tp){
var paging = `<ul class="pagination">`;
// 이전
if(sp > 1){
paging += `<li class="page-item"><a id="prev" class="page-link" href="javascript:void(0)">Previous</a></li>`;
}
// 페이지 번호
for(var i=sp; i<=ep; i++){
if(i == currentpage){
paging += `<li class="page-item active"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}else{
paging += `<li class="page-item"><a class="page-link pageno" href="javascript:void(0)">${i}</a></li>`;
}
}
// 다음
if(ep < tp){
paging += `<li class="page-item"><a id="next" class="page-link" href="javascript:void(0)">Next</a></li>`;
}
paging += `</ul>`;
return paging;
}
- http://localhost/boardpro/member/index.jsp
'대덕인재개발원 > 대덕인재개발원_Front End' 카테고리의 다른 글
231013_AJAX 강의 (0) | 2023.10.13 |
---|---|
231012_AJAX 강의 (0) | 2023.10.12 |
231010_AJAX 강의 (0) | 2023.10.10 |
231006_AJAX 강의 (0) | 2023.10.06 |
231005_AJAX 강의 (0) | 2023.10.05 |