[답변형게시판]
num : auto
writer
pass
subject
content
photo
readcount
(답변형 댓글 3가지 더 필요)
①regroup : 새글+예전글
②restep : 출력
③relevel :들여쓰기
writeday
regroup은 a글에 해당하는 답글들을 묶어줄 groupdyd column이다.
restep은 최종적으로 출력되는 순서를 나타낸다.
relevel은 댓글에 대해 들여쓰기를 표현한다.
restep과 relevel에 대한 설명이다.(네이버 댓글과는 순번이 약간 다르다)
<?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="board">
<select id="getTotalCountOfReboard" resultType="int">
select count(*) from reboard
</select>
<!-- num의 max값, null일 0 -->
<select id="maxNumOfReboard" resultType="int">
select ifnull(max(num),0) from reboard
</select>
<!-- 같은 그룹중에서 step보다 큰 데이터는 모두 +1 -->
<update id="updateStepOfReboard" parameterType="HashMap">
update reboard set restep=restep+1 where regroup=#{regroup} and restep>#{restep}
</update>
<!-- insert: 새글,답글 모두 해당 -->
<insert id="insertOfReboard" parameterType="bdto">
insert into reboard (writer,pass,subject,content,photo,regroup,restep,relevel,writeday) values (#{writer},#{pass},#{subject},#{content},#{photo},#{regroup},#{restep},#{relevel},now())
</insert>
<!-- 페이징 처리 전체 리스트 -->
<select id="selectPagingOfReboard" resultType="bdto" parameterType="HashMap">
select * from reboard order by regroup desc, restep asc limit #{start},#{perpage}
</select>
<!-- 하나의 dto값 얻기 -->
<select id="getDataOfReboard" parameterType="int" resultType="bdto">
select * from reboard where num=#{num}
</select>
<!-- readCount 증가 --> <!-- mapper에서는 무조건 sql 기준으로 값을 주고 받는다. -->
<update id="plusReadCountOfReboard" parameterType="int">
update reboard set readcount=readcount+1 where num=#{num}
</update>
<select id="checkPassEqualOfReboard" parameterType="HashMap" resultType="int">
select count(*) from reboard where num=#{num} and pass=#{pass}
</select>
<delete id="deleteOfReboard" parameterType="int">
delete from reboard where num=#{num}
</delete>
<update id="updateOfReboard" parameterType="bdto">
update reboard set subject=#{subject},content=#{content}
<if test="photo!='no'">
,photo=#{photo}
</if>
where num=#{num}
</update>
</mapper>
package spring.mvc.reboard;
import java.sql.Timestamp;
public class BoardDto {
private int num;
private String writer;
private String pass;
private String subject;
private String content;
private String photo;
private int readCount;
private int regroup;
private int restep;
private int relevel;
private Timestamp writeday;
private int acount;
public int getAcount() {
return acount;
}
public void setAcount(int acount) {
this.acount = acount;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getPhoto() {
return photo;
}
public void setPhoto(String photo) {
this.photo = photo;
}
public int getRegroup() {
return regroup;
}
public void setRegroup(int regroup) {
this.regroup = regroup;
}
public int getRestep() {
return restep;
}
public void setRestep(int restep) {
this.restep = restep;
}
public int getRelevel() {
return relevel;
}
public void setRelevel(int relevel) {
this.relevel = relevel;
}
public Timestamp getWriteday() {
return writeday;
}
public void setWriteday(Timestamp writeday) {
this.writeday = writeday;
}
public int getReadCount() {
return readCount;
}
public void setReadCount(int readCount) {
this.readCount = readCount;
}
}
public interface BoardDaoInter {
public int getTotalCount();
public int getMaxNum();
public void updateRestep(int regroup,int restep);
public void insertReboard(BoardDto bdto);
public List<BoardDto> getPagingList(int start,int perpage);
public BoardDto getData(int num);
public void updateReadCount(int num);
public int getCheckPass(int num,int pass);
public void deleteReboard(int num);
public void updateReboard(BoardDto bdto);
package spring.mvc.reboard;
import java.util.HashMap;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository // bean에 등록
public class BoardDao implements BoardDaoInter {
@Autowired
private SqlSession session;
@Override
public int getTotalCount() {
// TODO Auto-generated method stub
return session.selectOne("getTotalCountOfReboard");
}
@Override
public int getMaxNum() {
// TODO Auto-generated method stub
return session.selectOne("maxNumOfReboard");
}
@Override
public void updateRestep(int regroup, int restep) {
// TODO Auto-generated method stub
HashMap<String, Integer> map=new HashMap<String, Integer>();
// int를 integer(ref class)로 써야 합니다.
map.put("regroup", regroup);
map.put("restep", restep);
session.update("updateStepOfReboard", map);
}
@Override
public void insertReboard(BoardDto bdto) {
// TODO Auto-generated method stub
int num=bdto.getNum();
int regroup=bdto.getRegroup();
int restep=bdto.getRestep();
int relevel=bdto.getRelevel();
if(num==0) { // 새글
regroup=getMaxNum()+1;
restep=0;
relevel=0;
} else { // 답글
// 같은 그룹중 전달받은 restep보다 큰 글들은 모두 +1 해준다.
this.updateRestep(regroup, restep);
// 전달받은 step과 level 모두 +1
restep++;
relevel++;
}
// 바뀐 값들을 다시 dto에 담아줘야 합니다.
bdto.setRegroup(regroup);
bdto.setRestep(restep);
bdto.setRelevel(relevel);
// insert
session.insert("insertOfReboard", bdto);
}
@Override
public List<BoardDto> getPagingList(int start, int perpage) {
HashMap<String, Integer>map=new HashMap<String, Integer>();
map.put("start", start);
map.put("perpage", perpage);
return session.selectList("selectPagingOfReboard", map);
}
@Override
public BoardDto getData(int num) {
// TODO Auto-generated method stub
return session.selectOne("getDataOfReboard", num);
}
@Override
public void updateReadCount(int num) {
session.update("plusReadCountOfReboard", num);
}
@Override
public int getCheckPass(int num, int pass) {
// TODO Auto-generated method stub
HashMap<String, Integer>map=new HashMap<String, Integer>();
map.put("num", num);
map.put("pass", pass);
return session.selectOne("checkPassEqualOfReboard", map);
}
@Override
public void deleteReboard(int num) {
// TODO Auto-generated method stub
session.delete("deleteOfReboard", num);
}
@Override
public void updateReboard(BoardDto bdto) {
// TODO Auto-generated method stub
session.update("updateOfReboard", bdto);
}
}
답글
package board.data.controller;
@Controller
public class BoardListController {
@Autowired
BoardDao bdao;
@Autowired
AnswerDao adao;
@GetMapping("/board/list")
public ModelAndView list(@RequestParam(value = "currentPage",defaultValue = "1") int currentPage) {
ModelAndView mview=new ModelAndView();
// 페이징 처리에 필요한 변수선언
int totalCount=bdao.getTotalCount(); //전체객수
int totalPage; //총 페이지수
int startPage; //각블럭에서 보여질 시작페이지
int endPage; //각블럭에서 보여질 끝페이지
int startNum; //db에서 가져올 글의 시작번호(mysql은 첫글이 0,오라클은 1)
int perPage=10; //한페이지당 보여질 글의 갯수
int perBlock=3; //한블럭당 보여질 페이지 개수
int no; //각페이지당 출력할 시작번호
//총페이지수 구하기
//총글의 갯수/한페이지당 보여질 개수로 나눔(7/5=1)
//나머지가 1이라도 있으면 무조건 1페이지 추가(1+1=2페이지가 필요)
totalPage=totalCount/perPage+(totalCount%perPage==0?0:1);
//각블럭당 보여야할 시작페이지
//perBlock=5일경우는 현재페이지 1~5 시작:1 끝:5
//현재페이지 13 시작:11 끝:15
startPage=(currentPage-1)/perBlock*perBlock+1;
endPage=startPage+perBlock-1;
// 총페이지가 23일경우 마지막블럭은 25가아니라 23이다
if(endPage>totalPage)
endPage=totalPage;
//각페이지에서 보여질 시작번호
//1페이지: 0,2페이지:5 3페이지:10....
startNum=(currentPage-1)*perPage;
//각페이지당 출력할 시작번호 구하기 no
//총글개수가 23이면 1페이지 23,2페이지는 18,3페이지 13.....
//출력시 1씩 감소하며 출력
no=totalCount-(currentPage-1)*perPage;
// 각 페이지에서 필요한 게시글 가져오기
List<BoardDto> list=bdao.getPagingList(startNum, perPage);
// list의 각글에 댓글 갯수 표시하기
for(BoardDto d:list) {
d.setAcount(adao.getAnswerList(d.getNum()).size());
}
mview.addObject("totalCount", totalCount);
mview.addObject("list", list);
mview.addObject("startPage", startPage);
mview.addObject("endPage", endPage);
mview.addObject("totalPage", totalPage);
mview.addObject("no", no);
mview.addObject("currentPage", currentPage);
mview.setViewName("reboard/boardlist");
return mview;
}
}
package board.data.controller;
@Controller
public class BoardContentController {
@Autowired // 자동 주입
BoardDaoInter inter;
@Autowired // 댓글용 자동주입
AnswerDaoInter ainter;
@GetMapping("/board/content") // list에서 a태그 href에 있는 'content?' 라고 넘겨서 mapping 주소도 content이다.
public ModelAndView content(@RequestParam int num, @RequestParam String currentPage) { // boardlist 에서 보내준 2개의 값 다 받아줘야 한다.
ModelAndView mview=new ModelAndView();
// 조회수 증가
inter.updateReadCount(num);
// 넘어온 num에 대한 값들을 다시 dto에 넣어주기
BoardDto bdto=inter.getData(num);
// num에 해당하는 댓글을 DB에서 가져와서 보낸다.
List<AnswerDto> alist=ainter.getAnswerList(num);
mview.addObject("bdto", bdto);
mview.addObject("currentPage", currentPage);
// 댓글이 있을때에만 넘겨야 하므로..
mview.addObject("acount", alist.size());
mview.addObject("alist", alist);
mview.setViewName("reboard/content");
return mview;
}
}
package board.data.controller;
@Controller
public class BoardWriteController {
@Autowired
BoardDao bdao;
@GetMapping("/board/writeform")
public ModelAndView form(@RequestParam Map<String, String>map) {
ModelAndView mview=new ModelAndView();
// 아래 5개는 답글일 경우에만 넘어온다. 새글일 경우에는 안넘어온다.
String currentPage=map.get("currentPage");
String num=map.get("num");
String regroup=map.get("regroup");
String restep=map.get("restep");
String relevel=map.get("relevel");
System.out.println(currentPage+","+num);
// 입력폼에 hidden으로 넣어줘야함.. 답글일때 대비
mview.addObject("currentPage", currentPage==null?"1":currentPage); // 얘는 default 값을 1로 설정해줬음.
mview.addObject("num", num==null?"0":num);
mview.addObject("regroup", regroup==null?"0":regroup);
mview.addObject("restep", restep==null?"0":restep);
mview.addObject("relevel", relevel==null?"0":relevel);
// 0으로 넣어야 dao에서 새글로 인식
// 폼이 답글,새글 공용이므로..
mview.setViewName("reboard/writeform");
return mview;
}
@PostMapping("/board/insert")
public String insert(@ModelAttribute BoardDto bdto,@RequestParam ArrayList<MultipartFile>uimage,HttpSession session,
@RequestParam String currentPage) {
// 실제경로 구하기
String path=session.getServletContext().getRealPath("/WEB-INF/photo");
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
System.out.println(currentPage);
String photo="";
if(uimage.get(0).getOriginalFilename().equals("")) {
photo="no";
} else {
for(MultipartFile f:uimage) {
String fName=sdf.format(new Date())+"_"+f.getOriginalFilename();
photo+=fName+",";
try {
f.transferTo(new File(path+"/"+fName));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// photo에서 마지막 컴마 제거하기
photo=photo.substring(0, photo.length()-1);
}
// dto의 Photo에 넣기
bdto.setPhoto(photo);
// insert
bdao.insertReboard(bdto);
// insert되는 순간 생성된 content의 num값이 가장 큰 값이다. insert 된 파일을 바로 열기 위해 maxNum을 활용한다.
int maxNum=bdao.getMaxNum();
return "redirect:content?num="+maxNum+"¤tPage="+currentPage;
}
}
package board.data.controller;
@Controller
public class BoardUpdateController {
@Autowired
BoardDaoInter inter;
@GetMapping("/board/updatepassform")
public ModelAndView upassform(@RequestParam int num,@RequestParam int currentPage) {
ModelAndView mview=new ModelAndView();
mview.addObject("num", num);
mview.addObject("currentPage", currentPage);
mview.setViewName("reboard/updatepassform");
return mview;
}
@PostMapping("/board/updatepass")
public ModelAndView updatepass(@RequestParam int num,@RequestParam int pass,@RequestParam int currentPage) {
ModelAndView mview=new ModelAndView();
System.out.println(currentPage);
// 비밀번호가 맞으면 수정폼으로, 틀리면 passfail로 이동
int check=inter.getCheckPass(num, pass);
if(check==0) {
mview.setViewName("reboard/passfail");
} else {
BoardDto bdto=inter.getData(num);
mview.addObject("bdto", bdto);
mview.addObject("currentPage", currentPage);
mview.setViewName("reboard/updateform");
}
return mview;
}
@PostMapping("/board/update")
public String update(@ModelAttribute BoardDto bdto,
@RequestParam String currentPage,
@RequestParam ArrayList<MultipartFile>uimage,
HttpSession session) {
String path=session.getServletContext().getRealPath("WEB-INF/photo");
System.out.println(path);
System.out.println(currentPage);
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMddHHmmss");
String photo="";
if(uimage.get(0).getOriginalFilename().equals("")) {
photo="no";
} else {
// 수정전에 이전사진 지우기
String pre_photo=inter.getData(bdto.getNum()).getPhoto();
String []pre_fName=pre_photo.split(",");
for(String f:pre_fName) {
File file=new File(path+"/"+f);
file.delete();
}
for(MultipartFile f:uimage) {
String fName=sdf.format(new Date())+"_"+f.getOriginalFilename();
photo+=fName+",";
try {
f.transferTo(new File(path+"/"+fName));
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// photo에서 마지막 컴마 제거하기
photo=photo.substring(0, photo.length()-1);
}
// dto의 Photo에 넣기
bdto.setPhoto(photo);
// update
inter.updateReboard(bdto);
// 내용 수정 후 원래 페이지로 이동
return "redirect:content?num="+bdto.getNum()+"¤tPage="+currentPage;
}
}
package board.data.controller;
@Controller
public class BoardDeleteController {
@Autowired
BoardDaoInter inter;
@GetMapping("/board/deletepassform")
public ModelAndView dpassform(@RequestParam String num,@RequestParam String currentPage) {
ModelAndView mview=new ModelAndView();
mview.addObject("num", num);
mview.addObject("currentPage", currentPage);
mview.setViewName("reboard/delpassform");
return mview;
}
@PostMapping("/board/deletepass")
public ModelAndView deletepass(@RequestParam int num,@RequestParam int pass,
@RequestParam int currentPage,HttpSession session) {
ModelAndView mview=new ModelAndView();
// 비밀번호가 맞으면 삭제하고, 틀리면 passfail로 이동
int check=inter.getCheckPass(num, pass);
if(check==0) {
mview.setViewName("reboard/passfail");
} else {
String photo=inter.getData(num).getPhoto();
if(!photo.equals("no")) {
String [] fName=photo.split(",");
String path=session.getServletContext().getRealPath("/WEB-INF/photo");
for(String f:fName) {
File file=new File(path+"/"+f);
file.delete();
}
}
inter.deleteReboard(num);
mview.setViewName("redirect:list");
}
return mview;
}
}
댓글
<mapper namespace="answer">
<insert id="insertOfReanswer" parameterType="adto">
insert into reanswer (num,nickname,pass,contents,writeday) values(#{num},#{nickname},#{pass},#{contents},now())
</insert>
<select id="selectNumOfReanswer" parameterType="int" resultType="adto">
select * from reanswer where num=#{num} order by idx asc
</select>
<!-- 비밀번호 check -->
<select id="checkEqulPassOfReanswer" parameterType="HashMap" resultType="int">
select count(*) from reanswer where idx=#{idx} and pass=#{pass}
</select>
<!-- 삭제 -->
<delete id="deleteOfReanswer" parameterType="int">
delete from reanswer where idx=#{idx}
</delete>
</mapper>
package answer.data;
import java.sql.Timestamp;
public class AnswerDto {
private int idx;
private int num;
private String nickname;
private String pass;
private String contents;
private Timestamp writeday;
public int getIdx() {
return idx;
}
public void setIdx(int idx) {
this.idx = idx;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public String getContents() {
return contents;
}
public void setContents(String contents) {
this.contents = contents;
}
public Timestamp getWriteday() {
return writeday;
}
public void setWriteday(Timestamp writeday) {
this.writeday = writeday;
}
}
public interface AnswerDaoInter {
public void insertAnswer(AnswerDto adto);
public List<AnswerDto> getAnswerList(int num);
public int checkPassAnswer(int idx,String pass);
public void deleteAnswer(int idx);
package answer.data;
@Repository
public class AnswerDao implements AnswerDaoInter {
@Autowired
private SqlSession session;
@Override
public void insertAnswer(AnswerDto adto) {
// TODO Auto-generated method stub
session.insert("insertOfReanswer", adto);
}
@Override
public List<AnswerDto> getAnswerList(int num) {
// TODO Auto-generated method stub
return session.selectList("selectNumOfReanswer", num);
}
@Override
public int checkPassAnswer(int idx, String pass) {
// TODO Auto-generated method stub
HashMap<String, Object> map=new HashMap<String, Object>();
map.put("idx", idx);
map.put("pass", pass);
return session.selectOne("checkEqulPassOfReanswer", map);
}
@Override
public void deleteAnswer(int idx) {
// TODO Auto-generated method stub
session.delete("deleteOfReanswer", idx);
}
}
package answer.data;
@Controller
public class AnswerController {
@Autowired
AnswerDaoInter ainter;
@PostMapping("/board/ainsert")
public String answerinsert(@ModelAttribute AnswerDto adto,@RequestParam String currentPage) {
//DB에 추가
ainter.insertAnswer(adto);
return "redirect:content?num="+adto.getNum()+"¤tPage="+currentPage;
}
@GetMapping("/board/adelete")
@ResponseBody
public HashMap<String, Integer> answerDelete(@RequestParam int idx,@RequestParam String pass){ // {"idx":1}
int check=ainter.checkPassAnswer(idx, pass);
if(check==1) {
ainter.deleteAnswer(idx);
}
HashMap<String, Integer>map=new HashMap<String, Integer>();
map.put("check", check); // {"check":1}
return map;
}
}
출력jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 50px 50px;">
<table class="table table-bordered" style="width: 800px;">
<caption align="top">
<b>스프링 답변형 게시판</b>
<span style="float: right;">
<button type="button" class="btn btn-outline-info" onclick="location.href='writeform?currentPage=${currentPage}'">글쓰기</button>
</span>
</caption>
<tr>
<th width="60">번호</th>
<th width="300">제목</th>
<th width="220">작성자</th>
<th width="250">작성일</th>
<th width="60">조회</th>
</tr>
<c:if test="${totalCount==0 }">
<tr>
<td colspan="5" align="center">
<b>등록된 게시글이 없습니다.</b>
</td>
</tr>
</c:if>
<c:if test="${totalCount>0 }">
<c:forEach var="bdto" items="${list }" >
<tr>
<td align="center">${no }</td>
<c:set var="no" value="${no-1 }"></c:set> <!-- 출력 후 감소시키는것. 증감연산자 사용이 불가하기 때문이다. -->
<td> <!-- 제목 -->
<!-- relevel만큼 앞에 공백이 와야한다. -->
<c:forEach var="s" begin="1" end="${bdto.relevel }">
</c:forEach>
<!-- 답글인 경우에만 re.png이미지 출력 -->
<c:if test="${bdto.relevel>0 }">
<img alt="" src="../upload/re.png">
</c:if>
<!-- 제목.. 여기 누르면 내용 보기로 갈꺼다! -->
<a href="content?num=${bdto.num }¤tPage=${currentPage}">${bdto.subject }</a>
<!-- 댓글개수 표시하기 -->
<c:if test="${bdto.acount>0 }">
<a style="color: red;" href="content?num=${bdto.num }¤tPage=${currentPage}#answer">[${bdto.acount }]</a>
</c:if>
<!-- 사진이 있을경우 아이콘 표시 -->
<c:if test="${bdto.photo!='no' }">
<i class="bi bi-image"></i>
</c:if>
</td>
<td align="center"> ${bdto.writer }</td>
<td><fmt:formatDate value="${bdto.writeday }" pattern="yyyy-MM-dd"/></td>
<td align="center">${bdto.readCount }</td>
</tr>
</c:forEach>
</c:if>
</table>
<!-- 페이지번호 출력 -->
<c:if test="${totalCount>0 }">
<div style="width: 800px; text-align: center;">
<ul class="pagination justify-content-center">
<!-- 이전 -->
<c:if test="${startPage>1 }">
<li class="page-item">
<a href="list?currentPage=${startPage-1 }">이전</a>
</li>
</c:if>
<!-- 가운데 숫자들.. -->
<c:forEach var="pp" begin="${startPage }" end="${endPage }">
<c:if test="${currentPage==pp }">
<li class="page-item active">
<a href="list?currentPage=${pp }" class="page-link">${pp }</a>
</li>
</c:if>
<c:if test="${currentPage!=pp }">
<li class="page-item">
<a href="list?currentPage=${pp }" class="page-link">${pp }</a>
</li>
</c:if>
</c:forEach>
<!-- 다음 -->
<c:if test="${endPage<totalPage }">
<li class="page-item">
<a href="list?currentPage=${endPage+1 }">다음</a>
</li>
</c:if>
</ul>
</div>
</c:if>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 100px 100px;">
<table class="table table-bordered" style="width: 600px;">
<caption align="top"><b>내용보기</b></caption>
<tr>
<td>
<h2><b>${bdto.subject }</b></h2>
<span style="float: right; margin-right: 20px;">
조회: ${bdto.readCount }
<fmt:formatDate value="${bdto.writeday }" pattern="yyyy-MM-dd HH:mm"/>
</span>
<br>
<h5><b>작성자: ${bdto.writer }</b></h5>
</td>
</tr>
<tr>
<td>
<pre>${bdto.content }</pre>
<br><br>
<!-- 이미지가 있을때만 출력 -->
<c:if test="${bdto.photo!='no' }"> <!-- null이 아니다. DB 확인할 것!! -->
<c:forTokens var="pho" items="${bdto.photo }" delims=","> <!-- 사진 여러개의 경우 끊어서 사진 넣기 -->
<a href="../upload/${pho }"> <!-- 사진 클릭 시 원본사진 나오게 하기 -->
<img alt="" src="../upload/${pho }" width="150" style="border: 1px solid gray; border-radius: 10px;">
</a>
</c:forTokens>
</c:if>
</td>
</tr>
<!-- 댓글 -->
<tr>
<td>
<div id="answer">
<b>댓글: ${acount }</b><br><br>
<c:forEach var="a" items="${alist }">
${a.nickname }: ${a.contents }
<span style="color: gray;font-size: 0.8em;">
<fmt:formatDate value="${a.writeday }" pattern="yyyy-MM-dd HH:mm"/>
</span>
<i class="adel bi bi-eraser" style="color: red; cursor: pointer;" idx="${a.idx }"></i>
<br>
</c:forEach>
</div>
<form action="ainsert" method="post">
<input type="hidden" name="num" value="${bdto.num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<div class="d-inline-flex">
<b>닉네임: </b>
<input type="text" name="nickname" class="form-control" style="width: 120px;" required="required">
<b>비밀번호: </b>
<input type="password" name="pass" class="form-control" style="width: 120px;" required="required">
</div>
<br><br>
<div class="d-inline-flex">
<input type="text" name="contents" class="form-control" style="width: 500px;" placeholder="댓글내용을 입력하세요">
<button type="submit" class="btn btn-outline-info">확인</button>
</div>
</form>
</td>
</tr>
<tr>
<td align="right">
<button type="button" class="btn btn-info" onclick="location.href='writeform'" style="width: 100px;">글쓰기</button>
<button type="button" class="btn btn-success" onclick="location.href='writeform?num=${bdto.num}®roup=${bdto.regroup }&restep=${bdto.restep }&relevel=${bdto.relevel }¤tPage=${currentPage }'" style="width: 100px;">답글쓰기</button>
<button type="button" class="btn btn-warning" onclick="location.href='updatepassform?num=${bdto.num}¤tPage=${currentPage }'" style="width: 100px;">수정</button>
<button type="button" class="btn btn-danger" onclick="location.href='deletepassform?num=${bdto.num}¤tPage=${currentPage }'" style="width: 100px;">삭제</button>
<button type="button" class="btn btn-primary" onclick="location.href='list?currentPage=${currentPage}'" style="width: 100px;">목록</button>
</td>
</tr>
</table>
</div>
<script type="text/javascript">
$("i.adel").click(function(){
var idx=$(this).attr("idx");
var pass=prompt("비밀번호를 입력하세요","비밀번호");
if(pass==null){
return;
}
// alert(idx);
// alert(pass);
$.ajax({
type:"get",
dataType:"json",
url:"adelete",
data:{"pass":pass,"idx":idx},
success:function(res){
if(res.check==0){
alert("비밀번호가 맞지 않습니다.")
} else {
alert("댓글을 삭제합니다.");
location.reload();
}
}
});
});
</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 200px 200px;">
<form action="deletepass" method="post">
<input type="hidden" name="num" value="${num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<div class="alert alert-danger" style="width: 300px; font-size: 1.3em;">
<b>비밀번호를 입력해 주세요</b>
</div>
<div class="d-inline-flex">
<input type="password" name="pass" class="form-control" style="width: 120px;" required="required">
<button type="submit" class="btn btn-outline-danger">삭제하기</button>
<button type="button" class="btn btn-outline-success" onclick="history.back()">이전으로</button>
</div>
</form>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<script type="text/javascript">
alert("비밀번호가 맞지 않습니다.");
history.back();
</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 50px 100px;">
<form action="update" method="post" enctype="multipart/form-data">
<!-- hidden 2개 넣어주기 -->
<input type="hidden" name="num" value="${bdto.num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<table class="table table-bordered" style="width: 500px;">
<tr>
<th>작성자</th>
<td>
<input type="text" name="writer" class="form-control" required="required" style="width: 100px;" value="${bdto.writer }">
</td>
</tr>
<tr>
<th>제목</th>
<td>
<input type="text" name="subject" class="form-control" required="required" style="width: 300px;" value="${bdto.subject }">
</td>
</tr>
<tr>
<th>사진</th>
<td>
<input type="file" name="uimage" class="form-control" style="width: 220px;" multiple="multiple">
</td>
</tr>
<tr>
<td colspan="2">
<textarea style="width: 480px; height: 150px;" name="content" required="required" class="form-control">${bdto.content }</textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="btn btn-info" style="width: 100px;">수정하기</button>
<button type="button" class="btn btn-success" onclick="location.href='list'" style="width: 100px;">목록</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<h2>${currentPage }</h2>
<div style="margin: 200px 200px;">
<form action="updatepass" method="post">
<input type="hidden" name="num" value="${num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<div class="alert alert-warning" style="width: 300px; font-size: 1.3em;">
<b>비밀번호를 입력해 주세요</b>
</div>
<div class="d-inline-flex">
<input type="password" name="pass" class="form-control" style="width: 120px;" required="required">
<button type="submit" class="btn btn-outline-warning">수정하기</button>
<button type="button" class="btn btn-outline-success" onclick="history.back()">이전으로</button>
</div>
</form>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<link href="https://fonts.googleapis.com/css2?family=Bagel+Fat+One&family=Dongle:wght@300&family=East+Sea+Dokdo&family=Gamja+Flower&family=Gowun+Dodum&family=Nanum+Gothic+Coding&family=Nanum+Pen+Script&family=Orbit&display=swap" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<title>Insert title here</title>
</head>
<body>
<div style="margin: 50px 100px;">
<form action="insert" method="post" enctype="multipart/form-data">
<!-- hidden 5개 넣어주기 -->
<input type="hidden" name="num" value="${num }">
<input type="hidden" name="currentPage" value="${currentPage }">
<input type="hidden" name="regroup" value="${regroup }">
<input type="hidden" name="restep" value="${restep }">
<input type="hidden" name="relevel" value="${relevel }">
<table class="table table-bordered" style="width: 500px;">
<caption align="top"><b>
<c:if test="${num==0 }">새글쓰기</c:if>
<c:if test="${num!=0 }">답글쓰기</c:if>
</b></caption>
<tr>
<th>작성자</th>
<td>
<input type="text" name="writer" class="form-control" required="required" style="width: 100px;">
</td>
</tr>
<tr>
<th>비밀번호</th>
<td>
<input type="password" name="pass" class="form-control" required="required" style="width: 130px;">
</td>
</tr>
<tr>
<th>제목</th>
<td>
<input type="text" name="subject" class="form-control" required="required" style="width: 300px;">
</td>
</tr>
<tr>
<th>사진</th>
<td>
<input type="file" name="uimage" class="form-control" style="width: 220px;" multiple="multiple">
</td>
</tr>
<tr>
<td colspan="2">
<textarea style="width: 480px; height: 150px;" name="content" required="required" class="form-control"></textarea>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<button type="submit" class="btn btn-info" style="width: 100px;">저장하기</button>
<button type="button" class="btn btn-success" onclick="location.href='list'" style="width: 100px;">목록</button>
</td>
</tr>
</table>
</form>
</div>
</body>
</html>