TIL/academy

국비 TIL(Today I Learned) 20220901 갤러리 실습

토희 2022. 9. 1. 19:41
728x90

어제꺼 복습

EXCEPTION_INFO.jsp

예외발생했을때 exceptionResolver가 esception 객체를 돌려줌

 

 

 

첨부파일 할때 name이 있어야 작동함!!

아래 코드는 기존 T/update.jsp임

 

FileController.java에서 getFileMap()에서 name을 받아옴!!!

 

 

 

어제 갤러리 실습 오늘도 이어서!!

화면

기존에는 list랑 detail의 jsp가 분리되어있었다면, 이번에 만들때는

list가 오른쪽, detail이 왼쪽으로 가게끔 함

 

그래서 detail.jsp는 없고, ajax 처리함

 

로그인 한 사람이 글 작성한 사람이면 수정, 삭제 버튼이 활성화된다

 

 

update(수정)은 페이지가 이동하게끔 함

insert화면

 

 

 

전체 코드

AGController.java

package com.spring.sample.web.testa.Controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.spring.sample.common.service.IPagingService;
import com.spring.sample.web.testa.dao.IACDao;

@Controller
public class AGController {
	@Autowired
	public IACDao iACDao;

	@Autowired
	public IPagingService ips;

	@RequestMapping(value = "/AGList")
	public ModelAndView AGList(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {

		int page = 1;

		if (params.get("page") != null && params.get("page") != "") {
			page = Integer.parseInt(params.get("page"));
		}

		mav.addObject("page", page);
		mav.setViewName("testa/G/list");

		return mav;
	}

	@RequestMapping(value = "/AGListAjax", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String AGListAjax(@RequestParam HashMap<String, String> params) throws Throwable {
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> model = new HashMap<String, Object>();

		// 페이지 받아오게 되어있음
		int cnt = iACDao.getInt("G.getGCnt", params);

		HashMap<String, Integer> pd = ips.getPagingData(Integer.parseInt(params.get("page")), cnt, 9, 5);

		params.put("start", Integer.toString(pd.get("start")));
		params.put("end", Integer.toString(pd.get("end")));

		List<HashMap<String, String>> list = iACDao.getList("G.getGList", params);

		model.put("list", list);
		model.put("pd", pd);

		System.out.println(params.toString());

		return mapper.writeValueAsString(model);
	}

	@RequestMapping(value = "/AGInsert")
	public ModelAndView aGInsert(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {

		System.out.println(params.toString());

		mav.setViewName("testa/G/insert");

		return mav;
	}

	@RequestMapping(value = "/AGAction/{gbn}", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String AGAction(@PathVariable String gbn, @RequestParam HashMap<String, String> params) throws Throwable {
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> model = new HashMap<String, Object>();

		int cnt = 0;

		try {
			switch (gbn) {
			case "insert":
				cnt = iACDao.insert("G.insertG", params);
				break;
			case "update":
				cnt = iACDao.update("G.updateG", params);
				break;
			case "delete":
				cnt = iACDao.update("G.deleteG", params);
				break;
			}

			if (cnt > 0) {
				model.put("msg", "success");
			} else {
				model.put("msg", "fail");
			}
		} catch (Exception e) {
			e.printStackTrace();
			model.put("msg", "error");
		}

		return mapper.writeValueAsString(model);
	}

	// 가져오고 변경되는게 없기 때문에 비동기 처리로 안되도 됨
//	@RequestMapping(value = "/AGDetail")
//	public ModelAndView aGDetail(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
//		// 글번호 안 넘어왔을때 처리
//		if (params.get("no") != null && params.get("no") != "") {
//			// 조회수
//			iACDao.update("G.updateGHit", params);
//			HashMap<String, String> data = iACDao.getMap("G.getG", params);
//
//			mav.addObject("data", data);
//
//			mav.setViewName("testa/G/list");
//		}
//		/*
//		 * else { mav.setViewName("redirect:AGList"); }
//		 */
//		return mav;
//	}

	@RequestMapping(value = "/AGDetailAjax", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String AGDetailAjax(@RequestParam HashMap<String, String> params) throws Throwable {
		ObjectMapper mapper = new ObjectMapper();
		Map<String, Object> model = new HashMap<String, Object>();

		HashMap<String, String> data = iACDao.getMap("G.getG", params);

		model.put("data", data);

		System.out.println(params.toString());

		return mapper.writeValueAsString(model);
	}

	@RequestMapping(value = "/AGUpdate")
	public ModelAndView aGUpdate(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {

		System.out.println(params.toString());

		// 글번호 안 넘어왔을때 처리
		if (params.get("no") != null && params.get("no") != "") {
			HashMap<String, String> data = iACDao.getMap("G.getG", params);

			mav.addObject("data", data);

			mav.setViewName("testa/G/update");
		} else {
			mav.setViewName("redirect:AGList");
		}

		return mav;
	}

}

밑에 AGDetailAjax가 이번에 만든부분

주석 처리된곳이 기존에 detail

 

G_SQL.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="G">
	<select id="getGCnt" resultType="Integer" parameterType="hashmap">
		SELECT COUNT(*) AS CNT
		FROM GALLERY G INNER JOIN MEM M ON G.MEM_NO = M.MEM_NO
		AND M.DEL = 1
		WHERE G.DEL_DT IS NULL
	</select>
	
	<select id="getGList" resultType="hashmap" parameterType="hashmap">
		SELECT G.NO, G.PIC, G.TITLE, G.DISCRIPT, G.HIT, G.DT
		FROM (
		SELECT G.NO, G.PIC, G.TITLE, G.DISCRIPT, G.HIT, 
		CASE WHEN TO_CHAR(G.REG_DT,'YY.MM.DD') = TO_CHAR(SYSDATE, 'YY.MM.DD')
		        THEN TO_CHAR(G.REG_DT, 'HH24:MI')
		        ELSE TO_CHAR(G.REG_DT, 'YY.MM.DD')
		        END AS DT, 
                 ROW_NUMBER() OVER(ORDER BY G.NO DESC) AS RNUM
				FROM GALLERY G INNER JOIN MEM M ON G.MEM_NO = M.MEM_NO
                AND M.DEL = 1
				WHERE G.DEL_DT IS NULL ) G
                WHERE G.RNUM BETWEEN #{start} AND #{end}
	</select>
	
	<insert id="insertG" parameterType="hashmap">
		INSERT INTO GALLERY(NO, TITLE, MEM_NO, PIC, DISCRIPT)
		VALUES (GALLERY_SEQ.NEXTVAL, #{title} , #{memNo}, #{pic}, #{discript})
	</insert>
	 
	<select id="getG" parameterType="hashmap"  resultType="hashmap">
		SELECT G.NO, G.TITLE, G.MEM_NO, G.PIC, G.HIT, G.DISCRIPT,
	    TO_CHAR(G.REG_DT, 'YYYY-MM-DD') AS DT
		FROM GALLERY G INNER JOIN MEM M ON G.MEM_NO = M.MEM_NO
		AND M.DEL = 1
		WHERE G.DEL_DT IS NULL
		AND G.NO = #{no}
	</select>
	
	<update id="updateGHit" parameterType="hashmap">
		UPDATE GALLERY SET HIT = HIT + 1
		WHERE NO = #{no}
	</update>
	
	<update id="deleteG"  parameterType="hashmap">
		UPDATE GALLERY SET DEL_DT = TO_CHAR(SYSDATE, 'YY.MM.DD')
		WHERE NO = #{no}
	</update>
	
	<update id="updateG"  parameterType="hashmap">		
		UPDATE GALLERY SET TITLE = #{title},
		PIC = #{pic},
		DISCRIPT = #{discript}
		WHERE NO = #{no}
	</update>
</mapper>

 

IACDao.java

package com.spring.sample.web.testa.dao;

import java.util.HashMap;
import java.util.List;

public interface IACDao {
	// 숫자 취득
	public int getInt(String sql) throws Throwable; // 값 안 주고, 쿼리만 부를때

	public int getInt(String sql, HashMap<String, String> params) throws Throwable; // 값까지 줄때

	// 문자열 취득
	public String getString(String sql) throws Throwable;

	public String getString(String sql, HashMap<String, String> params) throws Throwable;

	// HashMap 취득
	public HashMap<String, String> getMap(String sql) throws Throwable;

	public HashMap<String, String> getMap(String sql, HashMap<String, String> params) throws Throwable;

	// List 취득
	public List<HashMap<String, String>> getList(String sql) throws Throwable;

	public List<HashMap<String, String>> getList(String sql, HashMap<String, String> params) throws Throwable;

	// 등록
	public int insert(String sql) throws Throwable;

	public int insert(String sql, HashMap<String, String> params) throws Throwable;

	// 수정
	public int update(String sql) throws Throwable;

	public int update(String sql, HashMap<String, String> params) throws Throwable;

	// 삭제
	public int delete(String sql) throws Throwable;

	public int delete(String sql, HashMap<String, String> params) throws Throwable;
}

ACDao.java

package com.spring.sample.web.testa.dao;

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
public class ACDao implements IACDao {
	@Autowired
	public SqlSession sqlSession;

	@Override
	public int getInt(String sql) throws Throwable {
		return sqlSession.selectOne(sql);
	}

	@Override
	public int getInt(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.selectOne(sql, params);
	}

	@Override
	public String getString(String sql) throws Throwable {
		return sqlSession.selectOne(sql);
	}

	@Override
	public String getString(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.selectOne(sql, params);
	}

	@Override
	public HashMap<String, String> getMap(String sql) throws Throwable {
		return sqlSession.selectOne(sql);
	}

	@Override
	public HashMap<String, String> getMap(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.selectOne(sql, params);
	}

	@Override
	public List<HashMap<String, String>> getList(String sql) throws Throwable {
		return sqlSession.selectList(sql);
	}

	@Override
	public List<HashMap<String, String>> getList(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.selectList(sql, params);
	}

	@Override
	public int insert(String sql) throws Throwable {
		return sqlSession.insert(sql);
	}

	@Override
	public int insert(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.insert(sql, params);
	}

	@Override
	public int update(String sql) throws Throwable {
		return sqlSession.update(sql);
	}

	@Override
	public int update(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.update(sql, params);
	}

	@Override
	public int delete(String sql) throws Throwable {
		return sqlSession.delete(sql);
	}

	@Override
	public int delete(String sql, HashMap<String, String> params) throws Throwable {
		return sqlSession.delete(sql, params);
	}
}

 

 

list.jsp (밑에 재수정한 코드 있음, 밑에 걸로 참고!!!)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.paging_area{
	display: block; 
	position: relative; 
	left: 0;
	margin-bottom: 10px;
	font-size: 14px;
}

.main{
	display: flex;
	padding: 100px 200px;
	justify-content: space-between;
}
.main > div {
	width: 700px;	
}

.left_area img {
	width: 680px;
	height: 400px;
	border-radius: 15px;
	
}



.table {
	border-collapse: collapse;
	width: 100%;
	margin: 15px 0px;
}

.right_area img{ 
	width: 200px;
	height: 180px;
	/* object-fit: cover; */
}

.table tbody tr {
	height: 40px;
	text-align: center;
	color: #7b7b7b;
	font-size: 10.5pt;
}

.table tbody tr {
	
}

.tbody img{
	cursor: pointer;
}

</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript" 
		src="resources/script/common/popup.js"></script>
<script type="text/javascript">
var flag = true;
$(document).ready(function () {

	//목록 조회
	reloadList();
	
	
	//페이징 버튼
	$(".paging_area").on("click", "span", function () {
		
		$("#page").val($(this).attr("page"));
		
		reloadList();
	})
	
	// 등록버튼
	$("#insertBtn").on("click", function () {
		console.log("1");
		
		$("#actionForm").attr("action", "AGInsert");
		$("#actionForm").submit();
	})
	

	$(".tbody").on("click", "td", function () {
		$("#no").val($(this).attr("no"));
		
	 	/* $("#actionForm").attr("action", "AGDetail");
		$("#actionForm").submit();  */
		
		// 단건을 ajax로 보내서 왼쪽 화면에 그려
		var params = $("#actionForm").serialize();
		
		
		$.ajax({
			url : "AGDetailAjax", //경로
			type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
			dataType: "json", // 데이터 형태
			data: params, // 보낼데이터
			success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
				//console.log(res); // 콘솔에  pd랑 list 값이 보임
				
				var html = "";
				
				html += "<tr>";
				html += "<td colspan=\"2\">";
				html += "<img alt=\"\" src=\"resources/upload/"+ res.data.PIC +"\">";
				html += "</td>"
				html += "</tr>"
				html += "<tr>";
				html += "<th>번호</th>"
				html += "<td>" + res.data.NO+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>제목</th>"
				html += "<td>" + res.data.TITLE+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>작성일</th>"
				html += "<td>" + res.data.DT+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>조회수</th>"
				html += "<td>" + res.data.HIT+ "</td>";
				html += "</tr>"
				html += "<th>내용</th>"
				html += "<td>" + res.data.DISCRIPT+ "</td>";
				html += "</tr>"
			

				$(".left_area tbody").html(html);
				
				
			 	var html1 ="";
				
		
				if("${sMemNo}" == res.data.MEM_NO){
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"deleteBtn\" onclick=\"deleteF()\">삭제</div>";
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"updateBtn\">수정</div>";
				}
			
				$(".left_area .btn_wrap").html(html1); 
				
				

			},
			error : function(request, status, error) { // 실패했을 때 함수실행
				console.log(request.responseText); // 실패 상세 태역
			}
		});
		
	})
	

	$(".btn_wrap").on("click", "#updateBtn", function () {
		$("#actionForm").attr("action","AGUpdate");
		$("#actionForm").submit();
		
	});
	
});

function deleteF() {
	// ajax사용 예정
	$("#deleteBtn").on("click", function () {
		  makePopup({
		         title : "알림",
		         contents : "삭제하시겠습니까?",
		         // draggable : true,
		         buttons : [{
		            name : "삭제",
		            func:function() {
		            	var params = $("#actionForm").serialize();
		    			
		    			$.ajax({
		    				url : "AGAction/delete", //restful api라는게 여기서 시작한다고?
		    				type : "POST", 
		    				dataType: "json", 
		    				data: params, 
		    				success : function(res) { 
		    					switch(res.msg){
		    					case "success" : 
		    						// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
								

									$("#actionForm").attr("action","AGList");
									$("#actionForm").submit();
		    						break;
		    					case "fail" :
		    						makeAlert("알림" , "삭제에 실패하였습니다.");
		    						break;
		    					case "error" :
		    						makeAlert("알림" , "삭제 중 문제가 발생하였습니다.");
		    						break;
		    					}
		    				},
		    				error : function(request, status, error) { 
		    					console.log(request.responseText); 
		    				}
		    			});
		            }
		         }, {
		            name : "취소"
		    }]
		});
	});
}


// 목록 조회 호출, ajax불러오기
function reloadList() {
	var params = $("#actionForm").serialize();
	
	$.ajax({
		url : "AGListAjax", //경로
		type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
		dataType: "json", // 데이터 형태
		data: params, // 보낼데이터
		success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
			console.log(res); // 콘솔에  pd랑 list 값이 보임
			drawList(res.list);
			drawPaging(res.pd);
	
			
		},
		error : function(request, status, error) { // 실패했을 때 함수실행
			console.log(request.responseText); // 실패 상세 태역
		}
	});
	
}


function drawList(list) {
	var html = "";

	var cnt = 0;
  	console.log(list[0].PIC);
  	
	for(var data of list){
		if(cnt == 0) {
			html += "<tr>";
		}
		
		html += "<td no=\"" + data.NO + "\">";
		html += "<img alt=\"\" src=\"resources/upload/"+ data.PIC +"\">";
		html += "</td>"
		
		if(cnt == 2) {
			html += "</tr>";
		}
		cnt++;
		
		if(cnt >= 3) {
			cnt = 0;
		}
	}   
	$(".tbody").html(html);
	
	
	//처음일때만..
	// 강제로 tr td
	// enter키 누린것처럼
	

	if("${param.no}" != "") { // param.no가 있다면
		console.log("${param.no}");
		flag = false; // 이거 없어도 되는데??음????
		
		$("td[no='${param.no}']").click();
	} else if(flag) {
		console.log("else")
		flag = false; // 이게 없으면 페이징하면 그 페이지에 첫번째로 다시 로드됨, 내가 보고있던 디테일이 아니라
		
		if($(".tbody").html() != "") { // .tbody에 데이터가 있다면
			$(".tbody").children().eq(0).children().eq(0).click(); // click()는 위에 있는 클릭이벤트를 지칭
		}
		
	}
	
}


function drawPaging(pd) {
	var html = "";
	
	html += "<span class=\"page_btn page_first\" page=\"1\">처음</span>";
	// 이전
	if($("#page").val() == "1"){
		html += "<span class=\"page_btn page_prev\" page=\"1\">이전</span>";
	} else{
		// 문자열을 숫자로 바꾸기위해 *1
		html += "<span class=\"page_btn page_prev\" page=\"" + ($("#page").val() *1 - 1) + "\">이전</span>";
	}
	
	for(var i = pd.startP; i <= pd.endP; i++){
		if($("#page").val() * 1 == i){ // 현재 페이지
			html += "<span class=\"page_btn_on\" page=\"" + i + "\">" + i + "</span>";
		} else { // 다른 페이지
			html += "<span class=\"page_btn\" page=\"" + i + "\">" + i + "</span>";
		}
	}
	
	if($("#page").val() *1 == pd.endP){ // 현재페이지가 마지막 페이지라면
		html += "<span class=\"page_btn page_next\" page=\"" +pd.maxP+ "\">다음</span>";
	} else {
		html += "<span class=\"page_btn page_next\" page=\"" + ($("#page").val() *1 + 1) + "\">다음</span>";
	}
	
	html += "<span class=\"page_btn page_last\" page=\"" +pd.maxP+ "\">마지막</span>";
	
	$(".paging_area").html(html);
                                                                     
}
</script>		
</head>
<body>
<c:import url="/testAHeader"></c:import>
<hr/>
<div class="main">
<form action="#" id="actionForm" method="post">
	<input type="hidden" name="no" id="no" value="${data.NO}"/>
	<input type="hidden" name="page" id="page" value="${page}" />
</form>
<div class="left_area">
<table class="board_table">
	<colgroup>
		<col width="100" />
		<col width="600" />
	</colgroup>	
	<thead>
	</thead>
	<tbody>
	
	</tbody>
</table>
<div class="btn_wrap">

</div>
</div>
<div class="right_area">
<table class="table">
	<colgroup>
		<col width="100" />
		<col width="100" />
		<col width="100" />
	</colgroup>
	<tbody class="tbody">
	</tbody>
</table>
<div class="paging_area"></div>
<c:if test="${!empty sMemNo}">
			<div class="cmn_btn_ml float_right_btn" id="insertBtn">등록</div>
</c:if>
</div>
</div>
</body>
</html>

 

insert.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글쓰기</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.wrap{
	width: 800px;
	margin: 0 auto;
}


</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript" 
		src="resources/script/jquery/jquery.form.js"></script>
<script type="text/javascript" 
		src="resources/script/common/popup.js"></script>
<!-- CKEditor -->
<!-- 제이쿼리 뒤에 나와야함, 제이쿼리 기반으로 동작하기 때문에 -->
<script type="text/javascript" src="resources/script/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
$(document).ready(function () {
	// 에디터 연결
	// CKEDITOR.replace(아이디, 옵션)
	CKEDITOR.replace("discript", {
		resize_enabled: false, // resize_enabled : 크기조절기능 활용여부
		language : "ko", // 사용언어
		enterMode: "2", // 엔터키처리방법. 2번이면 <br/>
		width : "100%", // 숫자일경우 px, 문자열일경우 css크기
		height : 400
	});
	
	$("#listBtn").on("click", function () {
		$("#backForm").submit();
	});
	
	$("#insertBtn").on("click", function () {
		// CKEditor의 값 취득
		// CKEDITOR.instances[아이디] : CKEditor중 아이디가 같은 것을 찾겠다.
		//.getData() : 작성중인 내용을 취득하겠다.
		$("#discript").val(CKEDITOR.instances['discript'].getData());
		
		if($.trim($("#title").val()) == ""){
			makeAlert("알림","제목 입력하세요." , function () {
				$("#title").focus();
			})
		} else if($.trim($("#discript").val()) == ""){
			makeAlert("알림","내용을 입력하세요." , function () {
				$("#discript").focus();
			})
		} else {
			// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
			// 폼 객체 취득
			var form = $("#actionForm");
			// ajaxForm 적용
			form.ajaxForm({
				success: function (res) { // 데이터 주고 받기 성공시
					if(res.result == "SUCCESS"){ // 파일 전송 성공
						// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
						if(res.fileName.length > 0){
							$("#pic").val(res.fileName[0]); // 올라간 파일명 보관		
						}
						// 3번 단계 글저장 시작, 기존테이터
						var params = $("#actionForm").serialize();
						
						$.ajax({
							url : "AGAction/insert", //restful api라는게 여기서 시작한다고?
							type : "POST", 
							dataType: "json", 
							data: params, 
							success : function(res) { 
								switch(res.msg){
								case "success" : 
									// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
								
									$("#backForm").submit();
									break;
								case "fail" :
									makeAlert("알림" , "등록에 실패하였습니다.");
									break;
								case "error" :
									makeAlert("알림" , "등록 중 문제가 발생하였습니다.");
									break;
								}
							},
							error : function(request, status, error) { 
								console.log(request.responseText); 
							}
						});  // 글저장 끝
						
					} else { // 문제발생
						makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
					}
				},
				error: function () { // 에러시
					makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
				}
			}); // ajaxForm 설정 끝
			
			
			// ajaxForm 실행
			form.submit();
			
		}
	});
});

</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="AGList" id="backForm" method="post">
	<input type="hidden" name="page" id="page" value="${param.page}" />
</form>
<!-- ajax쓰기 때문에 gbn 지움 -->
<div class="wrap">
	<form action="fileUploadAjax" id="actionForm" method="post" enctype="multipart/form-data">
		<input type="hidden" name="pic" id="pic" /> <!-- 실 저장된 파일명 보관용 -->
		<table class="board_detail_table">
			<tr>
				<th>제목</th>
				<td><input type="text" name="title" id="title" /></td>
			</tr>
			<tr>
				<th>작성자</th>
				<td>${sMemNm}<input type="hidden" name="memNo" value="${sMemNo}" /><br/></td>
			</tr>
			<tr>
				<th colspan="2">내용</th>
			</tr>
			<tr>
				<th colspan="2"><textarea rows="10" cols="30" name="discript" id=discript></textarea></th>
			</tr>			
			<tr>
				<th>첨부파일</th>
				<td><input type="file" name="pic" /></td>
			</tr>
		</table>
	</form>
	<div class="cmn_btn_ml float_right_btn" id="listBtn">목록</div>
	<div class="cmn_btn_ml float_right_btn" id="insertBtn">등록</div>
</div>
</body>
</html>

update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!-- jsl의 functions : el tag 추가옵션 -->
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>글수정</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.wrap{
	width: 800px;
	margin: 0 auto;
}

.pic {
	display: none;
}


</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript" 
		src="resources/script/jquery/jquery.form.js"></script>
<script type="text/javascript" 
		src="resources/script/common/popup.js"></script>
<!-- CKEditor -->
<!-- 제이쿼리 뒤에 나와야함, 제이쿼리 기반으로 동작하기 때문에 -->
<script type="text/javascript" src="resources/script/ckeditor/ckeditor.js"></script>
<script type="text/javascript">
$(document).ready(function () {
	// 에디터 연결
	// CKEDITOR.replace(아이디, 옵션)
	CKEDITOR.replace("discript", {
		resize_enabled: false, // resize_enabled : 크기조절기능 활용여부
		language : "ko", // 사용언어
		enterMode: "2", // 엔터키처리방법. 2번이면 <br/>
		width : "100%", // 숫자일경우 px, 문자열일경우 css크기
		height : 400
	});
	
	$("#cancelBtn").on("click", function () {
		$("#backForm").submit();
	});
	
	// 첨부파일 파일삭제 버튼 클릭시
	$("#fileDelBtn").on("click", function () {
		// 기존 파일 내역 영역 제거
		$(".picOld").remove();
		// 기존 값 제거
		$("#pic").val("");
		// 파일 선택 영역 제공 
		$(".pic").show();
	});
	
	$("#updateBtn").on("click", function () {
		// CKEditor의 값 취득
		// CKEDITOR.instances[아이디] : CKEditor중 아이디가 같은 것을 찾겠다.
		//.getData() : 작성중인 내용을 취득하겠다.
		$("#discript").val(CKEDITOR.instances['discript'].getData());
		
		if($.trim($("#title").val()) == ""){
			makeAlert("알림","제목 입력하세요." , function () {
				$("#title").focus();
			})
		} else if($.trim($("#discript").val()) == ""){
			makeAlert("알림","내용을 입력하세요." , function () {
				$("#discript").focus();
			})
		} else {
			// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
			// 폼 객체 취득
			var form = $("#actionForm");
			// ajaxForm 적용
			form.ajaxForm({
				success: function (res) { // 데이터 주고 받기 성공시
					if(res.result == "SUCCESS"){ // 파일 전송 성공
						// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
						if(res.fileName.length > 0){
							$("#pic").val(res.fileName[0]); // 올라간 파일명 보관		
						}
						// 3번 단계 글저장 시작, 기존테이터
						var params = $("#actionForm").serialize();
						
						$.ajax({
							url : "AGAction/update", //restful api라는게 여기서 시작한다고?
							type : "POST", 
							dataType: "json", 
							data: params, 
							success : function(res) { 
								switch(res.msg){
								case "success" : 
									$('#backForm').submit();
									break;
								case "fail" :
									makeAlert("알림" , "등록에 실패하였습니다.");
									break;
								case "error" :
									makeAlert("알림" , "등록 중 문제가 발생하였습니다.");
									break;
								}
							},
							error : function(request, status, error) { 
								console.log(request.responseText); 
							}
						});  // 글저장 끝
						
					} else { // 문제발생
						makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
					}
				},
				error: function () { // 에러시
					makeAlert("알림", "파일 업로드에<br/>문제가 발생하였습니다.")
				}
			}); // ajaxForm 설정 끝
			
			
			// ajaxForm 실행
			form.submit();
		}
	});
});

</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="AGList" id="backForm" method="post">
	<input type="hidden" name="no" value="${data.NO}" />
</form>
<!-- ajax쓰기 때문에 gbn 지움 -->
<div class="wrap">
	<form action="fileUploadAjax" id="actionForm" method="post" enctype="multipart/form-data">
	<input type="hidden" name="no" value="${data.NO}" />
		<table class="board_detail_table">
			<tr>
				<th>번호</th>
				<td>${data.NO}</td>
			</tr>
			<tr>
				<th>제목</th>
				<td><input type="text" name="title" id="title" value="${data.TITLE}"/></td>
			</tr>
			<tr>
				<th>작성자</th>
				<td>${sMemNm}</td>
			</tr>
			<tr>
				<th colspan="2">내용</th>
			</tr>
			<tr>
				<th colspan="2"><textarea rows="10" cols="30" name=discript id="discript">${data.DISCRIPT}</textarea></th>
			</tr>
			<tr>
				<th>첨부파일</th>
				<c:choose>
					<c:when test="${empty data.PIC}">
						<!-- 파일이 없을때 -->
						<td>
							<input type="file" name="picFile" />
							<input type="hidden" name="pic" id="pic"/>
						</td>
					</c:when>
					<c:otherwise>
					<!-- 파일이 있을때 -->
						<td>
							<span class="attOld"> <!-- 기존 파일 -->
								<!-- fn:length(대상) : 대상 문자열의 길이나 배열, 리스트의 크기를 가져온다 -->
								<c:set var="fileLength" value="${fn:length(data.PIC)}"></c:set>
								<!-- fn:substring(값, 숫자1, 숫자2) : 값을 숫자1이상부터, 숫자2미만까지, 인덱스 기준으로 자른다. -->
								<c:set var="fileName" value="${fn:substring(data.PIC, 20, fileLength)}"></c:set>
								${fileName}
								<div class="cmn_btn_ml float_right_btn" id="fileDelBtn">파일삭제</div>
							</span>
							<span class="att"> <!-- 기존 파일 삭제 후 새 파일 용도 -->
								<input type="file" name="picFile" />
								<input type="hidden" name="pic" id="pic" value="${data.PIC}"/>
							</span>
						</td>
					</c:otherwise>
				</c:choose>
			</tr>
		</table>
	</form>
	<div class="cmn_btn_ml float_right_btn" id="cancelBtn">취소</div>
	<div class="cmn_btn_ml float_right_btn" id="updateBtn">수정</div>
</div>
</body>
</html>

 

 

++ 그리고 팀원 분이 

만약 이런 function이 있으면 왜 data.PIC 대신 ${data.PIC}을 못쓰는지 질문했다

${data.PIC}... el태그....

 

https://epthffh.tistory.com/entry/Javascript-%EC%97%90%EC%84%9C-JSTL-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0-%EC%99%80-%EC%A3%BC%EC%9D%98%EC%82%AC%ED%95%AD

 

Javascript 에서 JSTL 사용하기 와 주의사항

기본적으로 JSTL은 자바 코드를 다루기에 적합한 커스텀 태그 라이브러리이고 Javascript는 웹 브라우저에서 사용되는 스크립트 프로그래밍 언어이고 내장객체에도 접근이 가능하다는 장점이있다

epthffh.tistory.com

https://epthffh.tistory.com/entry/JSTL-%EA%B3%BC-Javascript-%ED%98%BC%EC%9A%A9-%EC%82%AC%EC%9A%A9%EC%9D%98-%EC%8B%A4%EC%A0%9C%EC%82%AC%EB%A1%80

 

JSTL 과 Javascript 혼용 사용의 실제사례

원글 : https://okky.kr/article/432665 실무 개발중 Javascript 와 JSTL의 사용법을 헷갈려 해서 도움을 청하신분에게 답변을 해드렸습니다 잘못된 코드를 먼저 보겠습니다 -잘못된 코드1 1 2 3 4 5 6 7 8 9 10..

epthffh.tistory.com

 

 

java(jstl) => html(js) 이런순으로!!!!

 

 

++ 팀원분이

디테일을 팝업으로 뜨게 함, list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>      
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"><title>갤러리게시판</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
html, body{
   margin: 0;
   padding: 0;
   background-color: gray;
}

img {
   width: 200px;
   height: 180px;
}

.list{
   width: 100%;
   padding: 0;
   margin: 0; 
}
.list img{
   float: left;
   
}


@media screen and (max-width:991px) {
  .list div{
     width: 33.333333%;
  }
}

@media screen and (max-width:768px) {
  .list div{
     width: 50%;
  }
}

#searchTxt {
   width : 161px;
   height : 28px;
   padding : 0px 2px;
   text-indent: 5px;
   vertical-align : middle;
   border: 1px solid #d7d7d7;
   outline-color : #70adf9
}
.search_area {
   width: 700px;
   text-align: right;
   margin: 0 auto;
}

.board_area {
   width: 700px;
   margin: 0 auto;
}

.board_detail_table tbody .pconr {
   height: 220px;
}

.board_detail_table tbody .pcon {
   overflow: auto;
   width: 600px;
    height: 220px;
}

.att {
   display: inline-block;
   vertical-align: top;
   width: 18px;
   height: 18px;
   background-image: url('resources/images/attFile.png');
   background-size: cover;
}

#cateNo {
   min-width: 100px;
   height: 30px;
   vertical-align: middle;
   border: 1px solid #d7d7d7;
   float: left;
}
</style>
<script type="text/javascript"
      src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript"
      src="resources/script/common/popup.js"></script>   
<script type="text/javascript">
$(document).ready(function() {
   var params = $("#actionForm").serialize();
   
   // 등록 버튼
   $("#insertBtn").on("click", function() {
      
      $("#actionForm").attr("action", "AGalInsert");
      $("#actionForm").submit();      
   });
   
   $.ajax({
      url : "AGAListAjax", 
      type : "POST", 
      dataType : "json", 
      data : params, 
      success : function(res) {
         drawList(res.list);
      },
      error : function(request, status, error) { 
         console.log(request.responseText); 
      }
   });
   
   $("body").on("click", "div", function() {
      $("#no").val($(this).attr("no"));
      var params = $("#actionForm").serialize();
      
      
      $.ajax({
         type : "post",
         url : "AGADetailAjax",
         dataType : "json",
         data : params,
         success : function(res) {
            console.log(res);
      var html = "";      
      
      html += "      <form id=\"boardForm\">";
      html += "         <table class=\"board_detail_table\">";
      html += "            <colgroup>";
      html += "               <col width=\"100\"/>";
      html += "               <col width=\"600\"/>";
      html += "            </colgroup>";
      html += "            <tbody>";
      html += "            <tr>";
      html += "               <th>제목</th>";
      html += "               <td class=\"list\">" + res.data[0].TITLE  + "</td>";
      html += "            </tr>"; 
      html += "            </tbody>";
      html += "         </table>";
      html += "      </form>   ";  
      
         makePopup({
            depth : 2,
            width : 720,
            height : 500,
            bg : true,
            bgClose : false,
            title : "상세보기",
            contents : html,
            draggable : false,
            buttons : [{
               name : "수정",
               func:function() {
                  checkPass(function(res) {
                     if(result == "TRUE") {
                        closePopup(2);
                        updatePopup();
                     } else {
                        makeAlert("알림", "비밀번호가 틀렸습니다.");
                     }
                  });
               }
            }, {
               name : "취소",
   
            }]
         });
      } 
   });
});
   
 
}); // document

function drawList(list) {
   var html = "";
                         
   
   
   for(var data of list) {
         
      html += "<div no=\"" + data.NO + "\">";         
      html += "<img src=\"resources/upload/" + data.PIC + "\">";        
      html += "</div>";         
                            
   }                                                 
                                                     
   $(".list").html(html);
}
</script>         
</head>
<body>
<c:import url="/testAHeader"></c:import>
<div class="search_area">
   <form action="#" id="actionForm" method="post">
      <input type="hidden" name="no" id="no" />
      <div class="cmn_btn_ml" id="insertBtn">등록</div>
   </form>   
</div>
   <div class="list">
         <img src="resources/images/gal/img1.jpg">
         <img src="resources/images/gal/img2.jpg">
         <img src="resources/images/gal/img3.jpg">
         <img src="resources/images/gal/img4.jpg">
         <img src="resources/images/gal/img5.jpg">
         <img src="resources/images/gal/img6.jpg">
         <img src="resources/images/gal/img7.jpg">
         <img src="resources/images/gal/img8.jpg">
         <img src="resources/images/gal/img9.jpg">
         <img src="resources/images/gal/img10.jpg">
         <img src="resources/images/gal/img11.jpg">
         <img src="resources/images/gal/img12.jpg">
         <img src="resources/images/gal/img13.jpg">
         <img src="resources/images/gal/img14.jpg">
         <img src="resources/images/gal/img15.jpg">
         <img src="resources/images/gal/img16.jpg">
         <img src="resources/images/gal/img17.jpg">
         <img src="resources/images/gal/img18.jpg">
         <img src="resources/images/gal/img19.jpg">
         <img src="resources/images/gal/img20.jpg">
         <img src="resources/images/gal/img21.jpg">
         <img src="resources/images/gal/img22.jpg">
         <img src="resources/images/gal/img23.jpg">
         <img src="resources/images/gal/img24.jpg">
      </div>
      <table>
         <thead>
         <tr>
            <th>번호</th>
            <th>제목</th>
            <th>작성자</th>
            <th>작성일</th>
            <th>조회수</th>
         </tr>   
      </thead>
      <tbody></tbody>
      </table>

</body>
</html>

 

9.2일

++  list화면에서 삭제시에는 detail쪽에 이미지가 안뜨는 문제가 있어서 코드 수정함

1. 내가 한거

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.paging_area{
	display: block; 
	position: relative; 
	left: 0;
	margin-bottom: 10px;
	font-size: 14px;
}

.main{
	display: flex;
	padding: 100px 200px;
	justify-content: space-between;
}
.main > div {
	width: 700px;	
}

.left_area img {
	width: 680px;
	height: 400px;
	border-radius: 15px;
	
}



.table {
	border-collapse: collapse;
	width: 100%;
	margin: 15px 0px;
}

.right_area img{ 
	width: 200px;
	height: 180px;
	/* object-fit: cover; */
}

.table tbody tr {
	height: 40px;
	text-align: center;
	color: #7b7b7b;
	font-size: 10.5pt;
}

.table tbody tr {
	
}

.tbody img{
	cursor: pointer;
}

</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript" 
		src="resources/script/common/popup.js"></script>
<script type="text/javascript">
var flag = true;
$(document).ready(function () {

	//목록 조회
	reloadList();
	
	
	//페이징 버튼
	$(".paging_area").on("click", "span", function () {
		
		$("#page").val($(this).attr("page"));
		
		reloadList();
	})
	
	// 등록버튼
	$("#insertBtn").on("click", function () {
		console.log("1");
		
		$("#actionForm").attr("action", "AGInsert");
		$("#actionForm").submit();
	})
	

	$(".tbody").on("click", "td", function () {
		$("#no").val($(this).attr("no"));
		
	 	/* $("#actionForm").attr("action", "AGDetail");
		$("#actionForm").submit();  */
		
		// 단건을 ajax로 보내서 왼쪽 화면에 그려
		var params = $("#actionForm").serialize();
		
		
		$.ajax({
			url : "AGDetailAjax", //경로
			type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
			dataType: "json", // 데이터 형태
			data: params, // 보낼데이터
			success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
				console.log(res); // 콘솔에  pd랑 list 값이 보임
				
				var html = "";
				
				html += "<tr>";
				html += "<td colspan=\"2\">";
				html += "<img alt=\"\" src=\"resources/upload/"+ res.data.PIC +"\">";
				html += "</td>"
				html += "</tr>"
				html += "<tr>";
				html += "<th>번호</th>"
				html += "<td>" + res.data.NO+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>제목</th>"
				html += "<td>" + res.data.TITLE+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>작성일</th>"
				html += "<td>" + res.data.DT+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>조회수</th>"
				html += "<td>" + res.data.HIT+ "</td>";
				html += "</tr>"
				html += "<th>내용</th>"
				html += "<td>" + res.data.DISCRIPT+ "</td>";
				html += "</tr>"
			

				$(".left_area tbody").html(html);
				
				
			 	var html1 ="";
				
		
				if("${sMemNo}" == res.data.MEM_NO){
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"deleteBtn\" onclick=\"deleteF()\">삭제</div>";
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"updateBtn\">수정</div>";
				}
			
				$(".left_area .btn_wrap").html(html1); 
				
				

			},
			error : function(request, status, error) { // 실패했을 때 함수실행
				console.log(request.responseText); // 실패 상세 태역
			}
		});
		
	})
	

	$(".btn_wrap").on("click", "#updateBtn", function () {
		$("#actionForm").attr("action","AGUpdate");
		$("#actionForm").submit();
		
	});
	
});

function deleteF() {
	// ajax사용 예정
	$("#deleteBtn").on("click", function () {
		  makePopup({
		         title : "알림",
		         contents : "삭제하시겠습니까?",
		         // draggable : true,
		         buttons : [{
		            name : "삭제",
		            func:function() {
		            	var params = $("#actionForm").serialize();
		    			
		    			$.ajax({
		    				url : "AGAction/delete", //restful api라는게 여기서 시작한다고?
		    				type : "POST", 
		    				dataType: "json", 
		    				data: params, 
		    				success : function(res) { 
		    					switch(res.msg){
		    					case "success" : 
		    						// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
								

									$("#actionForm").attr("action","AGList");
									$("#actionForm").submit();
		    						break;
		    					case "fail" :
		    						makeAlert("알림" , "삭제에 실패하였습니다.");
		    						break;
		    					case "error" :
		    						makeAlert("알림" , "삭제 중 문제가 발생하였습니다.");
		    						break;
		    					}
		    				},
		    				error : function(request, status, error) { 
		    					console.log(request.responseText); 
		    				}
		    			});
		            }
		         }, {
		            name : "취소"
		    }]
		});
	});
}


// 목록 조회 호출, ajax불러오기
function reloadList() {
	var params = $("#actionForm").serialize();
	
	$.ajax({
		url : "AGListAjax", //경로
		type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
		dataType: "json", // 데이터 형태
		data: params, // 보낼데이터
		success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
			console.log(res); // 콘솔에  pd랑 list 값이 보임
			drawList(res.list);
			drawPaging(res.pd);
	
			
		},
		error : function(request, status, error) { // 실패했을 때 함수실행
			console.log(request.responseText); // 실패 상세 태역
		}
	});
	
}


function drawList(list) {
	var html = "";

	var cnt = 0;
  	console.log(list[0].PIC);
  	
	for(var data of list){
		if(cnt == 0) {
			html += "<tr>";
		}
		
		html += "<td no=\"" + data.NO + "\">";
		html += "<img alt=\"\" src=\"resources/upload/"+ data.PIC +"\">";
		html += "</td>"
		
		if(cnt == 2) {
			html += "</tr>";
		}
		cnt++;
		
		if(cnt >= 3) {
			cnt = 0;
		}
	}   
	$(".tbody").html(html);
	
	
	//처음일때만..
	// 강제로 tr td
	// enter키 누린것처럼
	

	if("${param.no}" != "") { // param.no가 있다면
		console.log("${param.no}");
		flag = false; 
		
		if($("td[no='${param.no}']").length == 0){ // 삭제 
			$(".tbody").children().eq(0).children().eq(0).click();
		} else { // 수정
			$("td[no='${param.no}']").click();
		}

	} else if(flag) {
		console.log("else")
		flag = false; // 이게 없으면 페이징하면 그 페이지에 첫번째로 다시 로드됨, 내가 보고있던 디테일이 아니라
		
		if($(".tbody").html() != "") { // .tbody에 데이터가 있다면
			$(".tbody").children().eq(0).children().eq(0).click(); // click()는 위에 있는 클릭이벤트를 지칭
		}
		
	}
	
}


function drawPaging(pd) {
	var html = "";
	
	html += "<span class=\"page_btn page_first\" page=\"1\">처음</span>";
	// 이전
	if($("#page").val() == "1"){
		html += "<span class=\"page_btn page_prev\" page=\"1\">이전</span>";
	} else{
		// 문자열을 숫자로 바꾸기위해 *1
		html += "<span class=\"page_btn page_prev\" page=\"" + ($("#page").val() *1 - 1) + "\">이전</span>";
	}
	
	for(var i = pd.startP; i <= pd.endP; i++){
		if($("#page").val() * 1 == i){ // 현재 페이지
			html += "<span class=\"page_btn_on\" page=\"" + i + "\">" + i + "</span>";
		} else { // 다른 페이지
			html += "<span class=\"page_btn\" page=\"" + i + "\">" + i + "</span>";
		}
	}
	
	if($("#page").val() *1 == pd.endP){ // 현재페이지가 마지막 페이지라면
		html += "<span class=\"page_btn page_next\" page=\"" +pd.maxP+ "\">다음</span>";
	} else {
		html += "<span class=\"page_btn page_next\" page=\"" + ($("#page").val() *1 + 1) + "\">다음</span>";
	}
	
	html += "<span class=\"page_btn page_last\" page=\"" +pd.maxP+ "\">마지막</span>";
	
	$(".paging_area").html(html);
                                                                     
}
</script>		
</head>
<body>
<c:import url="/testAHeader"></c:import>
<hr/>
<div class="main">
<form action="#" id="actionForm" method="post">
	<input type="hidden" name="no" id="no" value="${data.NO}"/>
	<input type="hidden" name="page" id="page" value="${page}" />
</form>
<div class="left_area">
<table class="board_table">
	<colgroup>
		<col width="100" />
		<col width="600" />
	</colgroup>	
	<thead>
	</thead>
	<tbody>
	
	</tbody>
</table>
<div class="btn_wrap">

</div>
</div>
<div class="right_area">
<table class="table">
	<colgroup>
		<col width="100" />
		<col width="100" />
		<col width="100" />
	</colgroup>
	<tbody class="tbody">
	</tbody>
</table>
<div class="paging_area"></div>
<c:if test="${!empty sMemNo}">
			<div class="cmn_btn_ml float_right_btn" id="insertBtn">등록</div>
</c:if>
</div>
</div>
</body>
</html>

 

 

 

2. 강사님이 고쳐주신거 (flag 사용) 강사님 삭제버튼도 고쳐주심, onclick이벤트 말고, 변하지 않는곳에 이벤트 걸음

 

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>게시판</title>
<!-- Common CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/cmn.css" />
<!-- Popup CSS -->
<link rel="stylesheet" type="text/css" href="resources/css/common/popup.css" />
<style type="text/css">
.paging_area{
	display: block; 
	position: relative; 
	left: 0;
	margin-bottom: 10px;
	font-size: 14px;
}

.main{
	display: flex;
	padding: 100px 200px;
	justify-content: space-between;
}
.main > div {
	width: 700px;	
}

.left_area img {
	width: 680px;
	height: 400px;
	border-radius: 15px;
	
}



.table {
	border-collapse: collapse;
	width: 100%;
	margin: 15px 0px;
}

.right_area img{ 
	width: 200px;
	height: 180px;
	/* object-fit: cover; */
}

.table tbody tr {
	height: 40px;
	text-align: center;
	color: #7b7b7b;
	font-size: 10.5pt;
}

.table tbody tr {
	
}

.tbody img{
	cursor: pointer;
}

</style>
<script type="text/javascript" src="resources/script/jquery/jquery-1.12.4.min.js"></script>
<script type="text/javascript" 
		src="resources/script/common/popup.js"></script>
<script type="text/javascript">
var flag = true;
$(document).ready(function () {

	//목록 조회
	reloadList();
	
	
	//페이징 버튼
	$(".paging_area").on("click", "span", function () {
		
		$("#page").val($(this).attr("page"));
		
		reloadList();
	})
	
	// 등록버튼
	$("#insertBtn").on("click", function () {
		console.log("1");
		
		$("#actionForm").attr("action", "AGInsert");
		$("#actionForm").submit();
	})
	

	$(".tbody").on("click", "td", function () {
		$("#no").val($(this).attr("no"));
		
	 	/* $("#actionForm").attr("action", "AGDetail");
		$("#actionForm").submit();  */
		
		// 단건을 ajax로 보내서 왼쪽 화면에 그려
		var params = $("#actionForm").serialize();
		
		
		$.ajax({
			url : "AGDetailAjax", //경로
			type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
			dataType: "json", // 데이터 형태
			data: params, // 보낼데이터
			success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
				console.log(res); // 콘솔에  pd랑 list 값이 보임
				
				var html = "";
				
				html += "<tr>";
				html += "<td colspan=\"2\">";
				html += "<img alt=\"\" src=\"resources/upload/"+ res.data.PIC +"\">";
				html += "</td>"
				html += "</tr>"
				html += "<tr>";
				html += "<th>번호</th>"
				html += "<td>" + res.data.NO+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>제목</th>"
				html += "<td>" + res.data.TITLE+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>작성일</th>"
				html += "<td>" + res.data.DT+ "</td>";
				html += "</tr>"
				html += "<tr>";
				html += "<th>조회수</th>"
				html += "<td>" + res.data.HIT+ "</td>";
				html += "</tr>"
				html += "<th>내용</th>"
				html += "<td>" + res.data.DISCRIPT+ "</td>";
				html += "</tr>"
			

				$(".left_area tbody").html(html);
				
				
			 	var html1 ="";
				
		
				if("${sMemNo}" == res.data.MEM_NO){
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"deleteBtn\">삭제</div>";
					html1 += "<div class=\"cmn_btn_ml float_right_btn\" id=\"updateBtn\">수정</div>";
				}
			
				$(".left_area .btn_wrap").html(html1); 
				
				

			},
			error : function(request, status, error) { // 실패했을 때 함수실행
				console.log(request.responseText); // 실패 상세 태역
			}
		});
		
	})
	

	$(".btn_wrap").on("click", "#updateBtn", function () {
		$("#actionForm").attr("action","AGUpdate");
		$("#actionForm").submit();
		
	});
	
	$("body").on("click", "#deleteBtn", function () {
		  makePopup({
		         title : "알림",
		         contents : "삭제하시겠습니까?",
		         // draggable : true,
		         buttons : [{
		            name : "삭제",
		            func:function() {
		            	var params = $("#actionForm").serialize();
		    			
		    			$.ajax({
		    				url : "AGAction/delete", //restful api라는게 여기서 시작한다고?
		    				type : "POST", 
		    				dataType: "json", 
		    				data: params, 
		    				success : function(res) { 
		    					switch(res.msg){
		    					case "success" : 
		    						flag = true; // 여기 수정
		    						
		    						// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
								
 
									reloadList(); // 여기 수정
									
									closePopup(); // 여기 수정
		    						break;
		    					case "fail" :
		    						makeAlert("알림" , "삭제에 실패하였습니다.");
		    						break;
		    					case "error" :
		    						makeAlert("알림" , "삭제 중 문제가 발생하였습니다.");
		    						break;
		    					}
		    				},
		    				error : function(request, status, error) { 
		    					console.log(request.responseText); 
		    				}
		    			});
		            }
		         }, {
		            name : "취소"
		    }]
		});
	});
	
});


// 목록 조회 호출, ajax불러오기
function reloadList() {
	var params = $("#actionForm").serialize();
	
	$.ajax({
		url : "AGListAjax", //경로
		type : "POST", // 전송방식(GET: 주소형태, POST : 주소 헤더 형태)
		dataType: "json", // 데이터 형태
		data: params, // 보낼데이터
		success : function(res) { //성공했을 때 결과를 res에 받고 함수 실행
			console.log(res); // 콘솔에  pd랑 list 값이 보임
			drawList(res.list);
			drawPaging(res.pd);
	
			
		},
		error : function(request, status, error) { // 실패했을 때 함수실행
			console.log(request.responseText); // 실패 상세 태역
		}
	});
	
}


function drawList(list) {
	var html = "";

	var cnt = 0;
  	console.log(list[0].PIC);
  	
	for(var data of list){
		if(cnt == 0) {
			html += "<tr>";
		}
		
		html += "<td no=\"" + data.NO + "\">";
		html += "<img alt=\"\" src=\"resources/upload/"+ data.PIC +"\">";
		html += "</td>"
		
		if(cnt == 2) {
			html += "</tr>";
		}
		cnt++;
		
		if(cnt >= 3) {
			cnt = 0;
		}
	}   
	$(".tbody").html(html);
	
	
	//처음일때만..
	// 강제로 tr td
	// enter키 누린것처럼
	

	if("${param.no}" != "") { // param.no가 있다면
		flag = false; // 이거 없어도 되는데??음????

		$("td[no='${param.no}']").click(); // 수정
	} else if(flag) {
		console.log("else")
		flag = false; // 이게 없으면 페이징하면 그 페이지에 첫번째로 다시 로드됨, 내가 보고있던 디테일이 아니라
		
		if($(".tbody").html() != "") { // .tbody에 데이터가 있다면
			$(".tbody").children().eq(0).children().eq(0).click(); // click()는 위에 있는 클릭이벤트를 지칭
		}
		
	}
	
}


function drawPaging(pd) {
	var html = "";
	
	html += "<span class=\"page_btn page_first\" page=\"1\">처음</span>";
	// 이전
	if($("#page").val() == "1"){
		html += "<span class=\"page_btn page_prev\" page=\"1\">이전</span>";
	} else{
		// 문자열을 숫자로 바꾸기위해 *1
		html += "<span class=\"page_btn page_prev\" page=\"" + ($("#page").val() *1 - 1) + "\">이전</span>";
	}
	
	for(var i = pd.startP; i <= pd.endP; i++){
		if($("#page").val() * 1 == i){ // 현재 페이지
			html += "<span class=\"page_btn_on\" page=\"" + i + "\">" + i + "</span>";
		} else { // 다른 페이지
			html += "<span class=\"page_btn\" page=\"" + i + "\">" + i + "</span>";
		}
	}
	
	if($("#page").val() *1 == pd.endP){ // 현재페이지가 마지막 페이지라면
		html += "<span class=\"page_btn page_next\" page=\"" +pd.maxP+ "\">다음</span>";
	} else {
		html += "<span class=\"page_btn page_next\" page=\"" + ($("#page").val() *1 + 1) + "\">다음</span>";
	}
	
	html += "<span class=\"page_btn page_last\" page=\"" +pd.maxP+ "\">마지막</span>";
	
	$(".paging_area").html(html);
                                                                     
}
</script>		
</head>
<body>
<c:import url="/testAHeader"></c:import>
<hr/>
<div class="main">
<form action="#" id="actionForm" method="post">
	<input type="hidden" name="no" id="no" value="${data.NO}"/>
	<input type="hidden" name="page" id="page" value="${page}" />
</form>
<div class="left_area">
<table class="board_table">
	<colgroup>
		<col width="100" />
		<col width="600" />
	</colgroup>	
	<thead>
	</thead>
	<tbody>
	
	</tbody>
</table>
<div class="btn_wrap">

</div>
</div>
<div class="right_area">
<table class="table">
	<colgroup>
		<col width="100" />
		<col width="100" />
		<col width="100" />
	</colgroup>
	<tbody class="tbody">
	</tbody>
</table>
<div class="paging_area"></div>
<c:if test="${!empty sMemNo}">
			<div class="cmn_btn_ml float_right_btn" id="insertBtn">등록</div>
</c:if>
</div>
</div>
</body>
</html>

기존

수정

728x90