20240219 스프링(웹표준 기술 - 모달 풋터,상세보기 모달,swal, 댓글창 만들기, 댓글 출력하기)

2024. 2. 19. 17:322023.11.21-2024.05.31

352p

20240219 웹표준 기술/ RESTAPI / PESTFULL

 

부트스트랩 >modal-footer

 

		<div class="mt-2">
                  <form action="./write" method="post" onsubmit="return writeCheck()" name="frm">
                     <input type="text" id="title" name="title" class="form-control mb-2" required="required" placeholder="제목을 입력하세요">
                     <textarea id="content" name="content" class="form-control mb-2 vh-500" required="required"></textarea>
                     <button type="submit" class="btn btn-info">글쓰기</button>
                   </form>
	        			</div>
	        		</div>
	        		<div class="modal-footer"></div>
	        		모달풋터
     			</div>
        	</div>

 

 

 

글쓰기 코드 복사해서 아래쪽에 붙여넣고 상세보기 모달 코드로 변경하기

 

id: write>detail로 변경

 

                  <form action="./write" method="post" onsubmit="return writeCheck()" name="frm">
                     <input type="text" id="title" name="title" class="form-control mb-2" required="required" placeholder="제목을 입력하세요">
                     <textarea id="content" name="content" class="form-control mb-2 vh-500" required="required"></textarea>
                     <button type="submit" class="btn btn-info">글쓰기</button>
                   </form>

 

 

form태그(아래 코드) 삭제> 제목<br>본문내용으로 변경

글쓰기 코드로 상세보기 만들고 수정한 코드

 	<!-- 20240219 상세보기 모달 만들기 --> 
        <div class="modal" id="detail">
        	<div class="modal-dialog modal-xl">
        		<div class="modal-content">
        			<div class="modal-header">
        			<h3 class="modal-title">상세보기</h3>
        			<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
        		</div>
	               <div class="modal-body">
               <div class="mt-2">
                 제목<br>
                 본문내용
	        			</div>
	        		</div>
	        		<div class="modal-footer"></div>
	        		모달 footer 
	        		<!-- 20240219 웹표준 기술/ RESTAPI / PESTFULL -->
     			</div>
        	</div>
        </div>

 

상세보기 버튼 만들어주기

	<!-- 페이징  -->
	<!-- 20240216 글쓰기 -->
	<button type="button" class="btn btn-Light" data-bs-toggle="modal" data-bs-target="#write">글쓰기</button>
	<button type="button" class="btn btn-Light" data-bs-toggle="modal" data-bs-target="#detail">상세보기</button>

 

 

tbody 안에 a링크 주석 삭제, onclick 추가

		<tbody>
			<c:forEach items="${list }" var="row">
			<tr>
				<td>${row.board_no }</td>
				<td class="title" onclick="detail()">
				<%-- <a href="./detail?no=${row.board_no }"> --%>
				${row.board_title }
				<c:if test="${row.comment gt 0 }">
				<span class="badge">${row.comment }</span> 
				</c:if>	
				<%-- [${row.comment }]"> --%>
				<!-- </a> -->
				</td>
				<td>${row.board_write }</td>
				<td>${row.board_date }</td>
				<td>${row.board_count }</td>
			</tr>
			</c:forEach>
		</tbody>

 

 

function writeCheck(){ 아래 function detail(){ 추가

detail을 누르면 상세보기 입니다가 뜨는지 보기

   		function detail(){
   			alert("상세보기 입니다.");

 

>246번 누르면 아래 창 나온다.

 

 

alert 말고 다른거 써보기

SweetAlert

 

https://sweetalert.js.org/

 

SweetAlert

You've arrived! How lovely. Let me take your coat. Oops! Seems like something went wrong! Delete important stuff? That doesn't seem like a good idea. Are you sure you want to do that?

sweetalert.js.org

 

Get started! 눌러서 들어가기

 

스크립트 위에 CDN 추가

 

   		function detail(){
   			swal("Good job!", "상세보기 입니다.", "success"); //title, text, icon
   			
   		}

 

버튼 사용하기 (, 잘써주기)

   		function detail(){
   			swal({
   				title : "Good job!", 
   				text : "상세보기 입니다.",
   				icon : "success",
   				button : "좋아요"
   			}); //title, text, icon,button

 

 

 

글번호 보여지게 하기

 

번호 넘어오는지 확인

   		function detail(no){
   			//swal("Good job!", "상세보기 입니다.", "success"); //title, text, icon
   			/*swal({
   				title : "Good job!", 
   				text : "상세보기 입니다.",
   				icon : "success",
   				button : "좋아요"
   			}); //title, text, icon,button */
   			alert(no);
   		}

 

swal 사용해서 번호 보기(글자를 꼭 써야한다)

   		function detail(no){
   			//swal("Good job!", "상세보기 입니다.", "success"); //title, text, icon
   			swal({
   				title : "Good job!", 
   				text : "번호는" +no,
   				icon : "success",
   				button : "좋아요"
   			}); //title, text, icon,button 
   		}

 

 

			function detail(no){
   			//swal("Good job!", "상세보기 입니다.", "success"); //title, text, icon
   			/*swal({
   				title : "Good job!", 
   				text : "번호는" +no,
   				icon : "success",
   				button : "좋아요"
   			}); //title, text, icon,button */
            
            //모달 보이기
   			let detailModal = new bootstrap.Modal('#detail', {});// {옵션}
   			detailModal.show();

 

 

 

 

<h5>안에 id 넣기

  	<!-- 20240219 상세보기 모달 만들기 --> 
        <div class="modal" id="detail">
        	<div class="modal-dialog modal-xl">
        		<div class="modal-content">
        			<div class="modal-header">
        			<h5 class="modal-title" id="modalTitle">상세보기</h5>

 

$ 적어주기

   			//모달 보이기
   			let detailModal = new bootstrap.Modal('#detail', {});// {옵션}
   			$("#modalTitle").text(no);
   			detailModal.show();

 

 

 

제이쿼리 CND 스크립트에 추가 하기

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js" integrity="sha512-v2CJ7UaYy4JwqLDIrZUI/4hqeoQieOmAZNXBeQyjo21dadnwR+8ZaIJVT8EE2iyI61OV8e6M8PP2/4hpQINQ/g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

 

 

 

id=modalContent 로 띄워주기

               <div class="mt-2" id="modalContent">
                 제목<br>
                 본문내용
	        			</div>

 

	//모달 보이기
   			let detailModal = new bootstrap.Modal('#detail', {});// {옵션}
   			$("#modalTitle").text(no);
   			$("#modalContent").text("변경된 내용입니다.");
   			detailModal.show();

 

 

ajax 작성

   	       $.ajax({
   	         url     : "/restDetail",
   	         type     : "post",
   	         dataType : "text",
   	         data     : {'no' : no}, // 날라갈 데이터(no) text -> json
   	         success  : function(data){
   	            alert(data);
   	         },
   	         error     : function(error){
   	            alert(error);
   	         }
   	      });

 

RestController.java 만들기

package org.mask.controller;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;

@Controller
public class RestController {
	
	@PostMapping("/restDetail")
	public String restDetail(@Param("no") int no) {
		System.out.println("restDetail : " + no);
		return "restDetail" + no;
	}
}

 

 

 

DTO 연결

@Controller
public class RestController {
	@Autowired
	private BoardService boardService;
	
	@PostMapping("/restDetail")
	public String restDetail(@Param("no") int no) {
		System.out.println("restDetail : " + no);
		BoardDTO detail = boardService.detail(no);
		System.out.println(detail.getBoard_title());
		System.out.println(detail.getBoard_content());
		
		return "restDetail" + no;
	}
}

 

 

console

 

 

 

package org.mask.controller;

import org.apache.ibatis.annotations.Param;
import org.mask.dto.BoardDTO;
import org.mask.service.BoardService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class RestController {
	@Autowired
	private BoardService boardService;
	
	@PostMapping("/restDetail")
	public @ResponseBody BoardDTO restDetail(@Param("no") int no) {
		//System.out.println("restDetail : " + no);
		BoardDTO detail = boardService.detail(no);
		//System.out.println(detail.getBoard_title());
		//System.out.println(detail.getBoard_content());
		
		return detail;
	}
}

 

 

title 나오게 alert하기

   	       $.ajax({
   	         url     : "/restDetail",
   	         type     : "post",
   	         dataType : "json",
   	         data     : {'no' : no}, // 날라갈 데이터(no) text -> json
   	         success  : function(data){
   	            alert(data.board_title);
   	         },
   	         error     : function(error){
   	            alert(error);
   	         }
   	      });	
   		}

 

 

 

모달로 내용이 나타나게 설정하기

 $.ajax({
   	         url     : "/restDetail",
   	         type     : "post",
   	         dataType : "json",
   	         data     : {'no' : no}, // 날라갈 데이터(no) text -> json
   	         success  : function(data){ //text ->json
   	            //alert(data.board_title);
   	        	$("#modalTitle").text(data.board_title);
				$("#modalContent").html(data.board_content);
				detailModal.show();
   	         },
   	         error     : function(error){
   	            alert(error);
   	         }
   	      });	
   		}

 

 

번호 누르면 모달창, 내용누르면 페이지 이동

	<tbody>
			<c:forEach items="${list }" var="row">
			<tr>
				<td onclick="detail(${row.board_no })">${row.board_no }</td>
				<td class="title" >
					<a href="./detail?no=${row.board_no }">
						${row.board_title }
						<c:if test="${row.comment gt 0 }">
							<span class="badge">${row.comment }</span> 
						</c:if>	
					</a>
				</td>
				<td>${row.board_write }</td>
				<td>${row.board_date }</td>
				<td>${row.board_count }</td>
			</tr>
			</c:forEach>
		</tbody>

 

 

 

 

 

detail.jsp 댓글창 넣주고, css 꾸미기

	<!-- 20240219 댓글창 -->
	<hr>
	<div>
		<form action="./commentWrite" method="post">
		<div class="row">
			<div class="col-8 col-xs-8 col-sm-10 col-md-11 col-xl-11">
				<textarea class="form-control"></textarea>
			</div>
			 <div class="col-4 col-xs-4 col-sm-2 col-md-1 col-xl-1">
				<button class="btn btn-primary">댓글쓰기</button>
			</div>
		</div>	
		</form>
	</div>
	
		</div>
	</section>

 

 

BoardController.java

 

	   //댓글쓰기 20240219 psd == 글번호, 댓글내용, 글쓴이
	   @PostMapping("/commentWrite")
	   public String commentWrite(){
		   System.out.println("접근.");
		   return "redirect:/detail";
	   }

 

 

 

 

detail.jsp 댓글쓰기 추가

<input type="hidden" name="no" value="${detail.board_no }"> 추가

				<button class="btn btn-primary">댓글쓰기</button>
			</div>
		</div>	
		<input type="hidden" name="no" value="${detail.board_no }">
		</form>
	</div>

 

페이지 소스 보기에서 no 값 오는지 확인

 

 

 

BoardController.java

//댓글쓰기 20240219 psd == 글번호, 댓글내용 comment, 글쓴이
	   @PostMapping("/commentWrite")
	   public String commentWrite(CommentDTO comment){
		   System.out.println("접근.");
		   return "redirect:/detail";
	   }

 

CommentDTO 만들기

 

package org.mask.controller;

import lombok.Data;

@Data
public class CommentDTO {
	   private int no;
	   private String comment, mid;
	
	
}

 

 

값오는지 확인하기

  //댓글쓰기 20240219 psd == 글번호, 댓글내용 comment, 글쓴이
	   @PostMapping("/commentWrite")
	   public String commentWrite(CommentDTO comment){
		   System.out.println("접근.");
		   System.out.println(comment.getNo());
		   System.out.println(comment.getComment());
		   System.out.println(comment.getMid());
		   return "redirect:/detail";
	   }

 

BoardService.java 생성해주기

//댓글쓰기 20240219 psd == 글번호, 댓글내용 comment, 글쓴이
	   @PostMapping("/commentWrite")
	   public String commentWrite(CommentDTO comment){
		   int result = boardService.commentWrite(comment);
		   System.out.println("댓글쓰기 결과" + result);
			/*
			 * System.out.println("접근."); System.out.println(comment.getNo());
			 * System.out.println(comment.getComment());
			 * System.out.println(comment.getMid());
			 */
		   return "redirect:/detail";
	   }

 

 

 

BoardService.java> commentWrite 만들기

//2024.02.19 댓글창
	public int write(WriteDTO dto) {
		dto.setMid("mask");
		
		return boardDAO.write(dto);
	}
	public int commentWrite(CommentDTO comment) {
		comment.setMid("mask");
		return boardDAO.commentWrite(comment);
	}

 

BoardDAO>commentWrite 만들기

public int commentWrite(CommentDTO comment) {
		return sqlSession.insert("board.commentWrite", comment);
	}

 

 

board-mapper.xml > id="commentWrite" 추가

	<insert id="commentWrite" parameterType="commentDTO">
		INSERT INTO comment (board_no, ccomment, mno) 
		VALUES (#{no}, #{comment}, (SELECT mno FROM member WHERE mid=#{mid}))
	</insert>

 

mybatis-config.xml >org.mask.dto.CommentDTO 추가

<typeAliases>
  		<typeAlias type="java.lang.Integer" alias="integer"/>
  		<typeAlias type="org.mask.dto.BoardDTO" alias="boardDTO"/>
  		<typeAlias type="org.mask.dto.WriteDTO" alias="writeDTO"/>
  		<typeAlias type="org.mask.dto.CommentDTO" alias="commentDTO"/>
  	</typeAliases>

 

 

 

BoardControll.java

//2024-02-15 psd 20240216.no잡기/20240219 댓글
	   @GetMapping("/detail")
	   public String detail(@RequestParam(value = "no", defaultValue="0", required = true) String no, Model model) {

 

 

댓글입력하고 글쓰기 누르면 500에러 떠서 봤더니 detail.jsp의 id class="" 부분이 맞지않아 컬럼이 없다고 나왔다.

수정하고 했더니 데이터베이스에 댓글 등록된다.

<hr>
		<div class="">
			<form action="./commentWrite" method="post">
			<div class="row">
				<div class="col-8 col-xs-8 col-sm-10 col-md-11 col-xl-11">
					<textarea class="form-control" name="comment"></textarea>
				</div>
				<div class="col-4 col-xs-4 col-sm-2 col-md-1 col-xl-1">
					<button class="btn btn-success">댓글 쓰기</button>
				</div>
			</div>
			<input type="hidden" name="no" value="${detail.board_no }">				
			</form>
		</div>
		
		</div>

 

 

 댓글 출력창

detail.jsp

 

BoardDTO comment 있는지 확인

package org.mask.dto;

import lombok.Data;

@Data
public class BoardDTO {
	private int board_no, board_count, comment;
	private String board_title, board_content, board_write, board_date;
}

board-mapper.xml >select id="detail"부분 수정

 <select id="detail" resultType="boardDTO" parameterType="Integer">
      SELECT b.board_no, b.board_title, b.board_content, m.mname as board_write, b.board_date, b.board_ip, 
      (SELECT COUNT(*) FROM comment WHERE board_no=b.board_no) AS comment 
      FROM board b JOIN member m ON b.mno=m.mno WHERE board_no=#{no} AND board_del ='1' <!-- mybatis 변수명 # -->
   </select>

 

BoardControll.java 수정

			   BoardDTO detail = boardService.detail(reNo);//날라오는게 어떤 모양이냐
			   model.addAttribute("detail" , detail);
			   
			   //2024.02.19 psd 댓글도 뽑기
			   System.out.println("댓글 수 : " + detail.getComment());
			   
			   return "detail";

 

Console창에 댓글수 출력 된다.

 

값붙이기

  if(detail.getComment()>0) {
	   List<CommentDTO> commentsList = boardService.commentList(reNo);
	   model.addAttributes("commentsList" , commentsList);
	 }
			   
	   return "detail";

 

 

BoardService > commentList 만들기

 

 

commentList>

 

 

 // 02.19 댓글 추가 -dao
	   public List<CommentDTO> commentsList(int no) {
	      return sqlSession.selectList("board.commentsList", no);
	   }

 

board-mapper.xml

	
	<select id="commentsList" parameterType="Integer" resultType="commentDTO">
		SELECT cno, ccoment, cdate, clike, mid, mname, cip
		FROM commentview
		WHERE board_no=#{no}
	</select>

 

 

CommentDTO 수정

package org.mask.dto;

import lombok.Data;

@Data
public class CommentDTO {
	private int no, board_no, clike, mno;
	private String comment, mid, cdate, mname, cip;
}

 

board-mapper.xml >resultMap 추가

resultType>resultMap으로 변경

 <!-- 2023.02.19  -->
  	<resultMap type="commentDTO" id="commentDTOmap">
  		<result column="con" property="no" />
  		<result column="board_no" property="board_no" />
  		<result column="ccomment" property="comment" />
  		<result column="cdate" property="cdate" />
  		<result column="clike" property="clike" />
  		<result column="mid" property="mid" />
  		<result column="mno" property="mno" />
  		<result column="mname" property="mname" />
  		<result column="cip" property="cip" />

  	</resultMap>
	<select id="commentsList" parameterType="Integer" resultMap="commentDTOmap">
		SELECT cno, ccomment, cdate, clike, mid, mname, cip
		FROM commentview
		WHERE board_no=#{no}
	</select>

 

detail.jsp 댓글출력창

<!-- 댓글 출력창 -->
		<c:forEach items="${commentsList } var="c">
			${c.no } / ${c.comment } / ${c.cdate} / ${c.clike }/
			${c.mno } / ${c.mid } / ${c.mname} / ${c.cip }<br>
		</c:forEach>
		</div>

 

css 수정 > 부트스트랩 사용

		<!-- 2024.02.19댓글 출력창 -->
		<div class="mt-2">
			<c:forEach items="${commentsList }" var="c">
			<div class="mt-4">
				<div class="bg-warning bg-success row my-1 p-2">
					<div class="col-7">${c.mname }</div>
					<div class="col-2">${c.cip }</div>
					<div class="col-2">${c.cdate }</div>
					<div class="col-2">${c.clike }</div>
				</div>
				<div class="mx-5 mt-1" style="min-height: 80px">${c.comment }</div>		
			</div>
			</c:forEach>
		</div>		
		</div>

 

 

글쓴사람 뒤쪽으로 아이콘 넣어주기

이미지는 아이콘 파인더에서 찾아서 저장

			<div class="card mb-4" style="min-height: 500px;">
				<div class="card-body">
					<div class="h2">${detail.board_title }</div>
					<div class="row p-2 bg-Light">
						<div class="col align-middle text-start">
						${detail.board_write }
						<img alt="update" src="./img/update.png">
						<img alt="delete" src="./img/delete.png">
						</div>
						<div class="col align-middle text-end">${detail.board_date }</div>
					</div>
					<div class="mt-4 h-auto">${detail.board_content }</div>
				</div>
			</div>

 

 

삭제하기 만들기

<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script type="text/javascript">
function deletePost(){
   Swal.fire({
        title: "글을 삭제합니다",
        //text: "post를 삭제합니다.",
        icon: "warning",
        showCancelButton: true,
        confirmButtonText: "Yes",
        cancelButtonText: "No",
      }).then(result => {
        if (result.isConfirmed) {
          Swal.fire("삭제했습니다.","", "success");
        }
      });
   
}