카테고리 없음

국비 TIL(Today I Learned) 20220826 카테고리별 게시판

토희 2022. 8. 26. 13:27
728x90

list.jsp에 추가

 

 

카테고리 관련 데이터를 취득

 

list.jsp 변경

 

T_SQL.XML에 추가

AND T.CATE_NO = #{cateNo} 등등 cata관련 추가

<?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="T">
	<select id="getTCnt" resultType="Integer" parameterType="hashmap">
		SELECT COUNT(*) AS CNT
		FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
		AND M.DEL = 1
		WHERE T.DEL = 1
		AND T.CATE_NO = #{cateNo}
		<if test="searchTxt != null and searchTxt !=''">
			<choose>
				<when test="searchGbn eq 0">
					AND T.TITLE LIKE '%' || #{searchTxt} || '%'
				</when>
				<when test="searchGbn eq 1">
					AND M.MEM_NM LIKE '%' ||  #{searchTxt} || '%'
				</when>
			</choose>
		</if>
	</select>
	
	<select id="getTList" resultType="hashmap" parameterType="hashmap">
		SELECT T.NO, T.TITLE, T.MEM_NM, T.HIT, T.DT, T.ATT
		FROM(
		SELECT T.NO, T.TITLE, M.MEM_NM, T.HIT,
		CASE WHEN TO_CHAR(DT,'YY.MM.DD') = TO_CHAR(SYSDATE, 'YY.MM.DD')
		        THEN TO_CHAR(DT, 'HH24:MI')
		        ELSE TO_CHAR(DT, 'YY.MM.DD')
		        END AS DT, ATT,
		        ROW_NUMBER() OVER(ORDER BY T.NO DESC) AS RNUM
				FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
				AND M.DEL = 1
		WHERE T.DEL = 1
		AND T.CATE_NO = #{cateNo}
		<if test="searchTxt != null and searchTxt !=''">
			<choose>
				<when test="searchGbn eq 0">
					AND T.TITLE LIKE '%' || #{searchTxt} || '%'
				</when>
				<when test="searchGbn eq 1">
					AND M.MEM_NM LIKE '%' ||  #{searchTxt} || '%'
				</when>
			</choose>
		</if>) T
		WHERE T.RNUM BETWEEN #{start} AND #{end}
	</select>
	
	<insert id="insertT" parameterType="hashmap">
		INSERT INTO TBOARD(NO, TITLE, MEM_NO, CON, ATT, CATE_NO)
		VALUES (TBOARD_SEQ.NEXTVAL, #{title} , #{memNo}, #{con}, #{att}, #{cateNo})
	</insert>
	 
	<select id="getT" parameterType="hashmap"  resultType="hashmap">
		SELECT T.NO, T.TITLE, M.MEM_NO, M.MEM_NM, T.CON, T.HIT,
	    TO_CHAR(T.DT, 'YYYY-MM-DD') AS DT, T.ATT
		FROM TBOARD T INNER JOIN MEM M ON T.MEM_NO = M.MEM_NO
		AND M.DEL = 1
		WHERE T.DEL = 1
		AND T.NO = #{no}
	</select>
	
	<update id="updateTHit" parameterType="hashmap">
		UPDATE TBOARD SET HIT = HIT + 1
		WHERE NO = #{no}
	</update>
	
	<update id="deleteT"  parameterType="hashmap">
		UPDATE TBOARD SET DEL = 0
		WHERE NO = #{no}
	</update>
	
	<update id="updateT"  parameterType="hashmap">		
		UPDATE TBOARD SET TITLE = #{title},
		CON = #{con},
		ATT = #{att}
		WHERE NO = #{no}
	</update>
</mapper>

 

코드형 게시판 

동시에 여러개의 테이블을 하나의 게시판으로 

 

 

블로그는 카테고리 대신 내 아이디를 항상 조건으로!

 

 

다음주, 스케줄링 관련

주기적으로 도는 프로그램

특정 요일에 도는 프로그램

 

쓰는건 간단, 이해하는게 어렵

 

Restful Controller -> jsp관련

 

 

 

 

T에 있는 화면 수정 T를 카테고리 자유게시판으로

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">
#searchTxt{
width: 160px;
height: 30px; 
padding: 0px 2px;
text-indent: 5px;
vertical-align: middle;
border: 1px solid #d7d7d7; 
outline-color: #70adf9;
box-sizing: border-box;
}
.search_area{
	width: 800px;
	text-align: right;
	margin: 0 auto;
}
.board_area{
	width: 800px;
	margin: 0 auto;
}

.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; 
	boder: 1px soild #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 () {
	if("${params.searchGbn}" != ""){
		$("#searchGbn").val("${param.searchGbn}");
	} else {
		$("#oldGbn").val("0");
	}
	
	// 카테고리 설정
	if("${param.cateNo}" != ""){
		$("#cateNo").val("${param.cateNo}");
	}
	// 카테고리 변경시
	$("#cateNo").on("change", function () {
		// 검색 및 페이징 초기화
		$("#page").val("1");
		$("#searchGbn").val("0");
		$("#searchTxt").val("");
		$("#oldGbn").val("0");
		$("#oldTxt").val("");
		//목록 조회
		reloadList();
	})
	
	
	//목록 조회
	reloadList();
	
	//검색버튼
	$("#searchBtn").on("click", function () {
		$("#page").val("1");
		// 이동을 안하다보니 문제가 기존검색값 셋팅을 안해줌
		// 그래서  신규 상태 적용
		$("#oldGbn").val($("#searchGbn").val());
		$("#oldTxt").val($("#searchTxt").val());
		
		
		// 데이터만 가져와서 다시 그려줌, 화면 이동 없음
		reloadList();
	});
	
	//페이징 버튼
	$(".paging_area").on("click", "span", function () {
		// 기존 검색상태 유지
		$("#searchGbn").val($("#oldGbn").val());
		$("#searchTxt").val($("#oldTxt").val());
			
		
		$("#page").val($(this).attr("page"));
		
		reloadList();
	})
	
	// 등록버튼
	$("#insertBtn").on("click", function () {
		// 기존 검색상태 유지
		$("#searchGbn").val($("#oldGbn").val());
		$("#searchTxt").val($("#oldTxt").val());
		
		$("#actionForm").attr("action", "ATInsert");
		$("#actionForm").submit();
	})
	
	$("tbody").on("click", "tr", function () {
		$("#no").val($(this).attr("no"));
		
		$("#searchGbn").val($("#oldGbn").val());
		$("#searchTxt").val($("#oldTxt").val());
		
		$("#actionForm").attr("action", "ATDetail");
		$("#actionForm").submit();
	})
});

// 목록 조회 호출, ajax불러오기
function reloadList() {
	var params = $("#actionForm").serialize();
	
	$.ajax({
		url : "ATListAjax", //경로
		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 = "";
	
	// list에는 map이 들어있으니까 하나씩 꺼내오겠다
	for(var data of list){
		console.log(typeof(data.ATT) !="undefined");
		html += "<tr no=\"" + data.NO + "\">";
		html += "<td>" + data.NO + "</td>";
		html += "<td>";
		html += data.TITLE;
		if(typeof(data.ATT) !="undefined"){ // 첨부파일이 있다면
			html += "<span class=\"att\"></span>";
		}
		html += "</td>";
		html += "<td>" + data.MEM_NM + "</td>";
		html += "<td>" + data.DT + "</td>";
		html += "<td>" + data.HIT + "</td>";
		html += "</tr>";
	}   
	
	$("tbody").html(html);
}

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/>
<!-- 페이징 때 기존 검색 내용 유지용 -->
<input type="hidden" id="oldGbn" value="${param.searchGbn}"/>
<input type="hidden" id="oldTxt" value="${param.searchTxt}"/>

<!-- 데이터 후 처리해서 로딩이 빨라 -->
<div class="search_area">
	<!--  method="post"는 나중에 쓸 예정, no 보낼때 -->
	<form action="#" id="actionForm" method="post">
	<select name="cateNo" id="cateNo">
		<c:forEach var="data" items="${cate}">
			<option value="${data.CATE_NO}">${data.CATE_NM}</option>
		</c:forEach>
	</select>
	<input type="hidden" name="no" id="no" />
		<input type="hidden" name="page" id="page" value="${page}" />
		<select name="searchGbn" id="searchGbn">
			<option value="0">제목</option>
			<option value="1">작성자</option>
		</select>
		<input type="text" name="searchTxt" id="searchTxt" value="${param.searchTxt}" />
		<div class="cmn_btn_ml" id="searchBtn">검색</div>
		<c:if test="${!empty sMemNo}">
			<div class="cmn_btn_ml" id="insertBtn">등록</div>
		</c:if>
	</form>
</div>
<div class="board_area">
<table class="board_table">
	<colgroup>
		<col width="100" />
		<col width="400" />
		<col width="100" />
		<col width="100" />
		<col width="100" />
	</colgroup>
	<thead>
		<tr>
			<th>번호</th>
			<th>제목</th>
			<th>작성자</th>
			<th>작성일</th>
			<th>조회수</th>
		</tr>
	</thead>
	<tbody></tbody>
</table>
<div class="paging_area"></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("con", {
		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() : 작성중인 내용을 취득하겠다.
		$("#con").val(CKEDITOR.instances['con'].getData());
		
		if($.trim($("#title").val()) == ""){
			makeAlert("알림","제목 입력하세요." , function () {
				$("#title").focus();
			})
		} else if($.trim($("#con").val()) == ""){
			makeAlert("알림","내용을 입력하세요." , function () {
				$("#con").focus();
			})
		} else {
			// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
			// 폼 객체 취득
			var form = $("#actionForm");
			// ajaxForm 적용
			form.ajaxForm({
				success: function (res) { // 데이터 주고 받기 성공시
					if(res.result == "SUCCESS"){ // 파일 전송 성공
						// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
						if(res.fileName.length > 0){
							$("#att").val(res.fileName[0]); // 올라간 파일명 보관		
						}
						// 3번 단계 글저장 시작, 기존테이터
						var params = $("#actionForm").serialize();
						
						$.ajax({
							url : "ATAction/insert", //restful api라는게 여기서 시작한다고?
							type : "POST", 
							dataType: "json", 
							data: params, 
							success : function(res) { 
								switch(res.msg){
								case "success" : 
									// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
									$("#searchGbn").val("0");
									$("#searchTxt").val("");
								
									$("#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="ATList" id="backForm" method="post">
	<input type="hidden" name="page" id="page" value="${param.page}" />
	<input type="hidden" name="searchGbn" id="searchGbn" value="${param.searchGbn}"/>
	<input type="hidden" name="searchTxt" id="searchTxt" value="${param.searchTxt}"/>
	<!-- 전화면에서 넘어온 카테고리 번호 -->
	<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</form>
<!-- ajax쓰기 때문에 gbn 지움 -->
<div class="wrap">
	<form action="fileUploadAjax" id="actionForm" method="post" enctype="multipart/form-data">
		<input type="hidden" name="att" id="att" /> <!-- 실 저장된 파일명 보관용 -->
		<table class="board_detail_table">
			<tr>
				<th>카테고리</th>
				<td>${cateNm}<input type="hidden" name="cateNo"value="${param.cateNo}"/></td>
			</tr>
			<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="con" id="con"></textarea></th>
			</tr>
			
			<tr>
				<th>첨부파일</th>
				<td><input type="file" name="attFile" /></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>

detail.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;
}
.con{
text-align: left; 
min-height: 400px;
}
</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 () {
	$("#listBtn").on("click", function() {
		$("#actionForm").attr("action","ATList"); 
		$("#actionForm").submit();
	});
	
	// ajax사용 예정
	$("#deleteBtn").on("click", function () {
		  makePopup({
		         title : "알림",
		         contents : "삭제하시겠습니까?",
		         // draggable : true,
		         buttons : [{
		            name : "삭제",
		            func:function() {
		            	var params = $("#actionForm").serialize();
		    			
		    			$.ajax({
		    				url : "ATAction/delete", //restful api라는게 여기서 시작한다고?
		    				type : "POST", 
		    				dataType: "json", 
		    				data: params, 
		    				success : function(res) { 
		    					switch(res.msg){
		    					case "success" : 
		    						// 카테고리를 유지하고 나머지 정보 초기화
									$("#page").val("1");
									$("#searchGbn").val("0");
									$("#searchTxt").val("");
								

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

</script>
</head>
<body>
<c:import url="/testAHeader"></c:import>
<form action="#" id="actionForm" method="post">
	<input type="hidden" name="gbn" value="d"> <!-- selRes는 gbn을 받게 되어있어서 값을 추가해줘야함, 이 화면에서는 없어도 됨 -->
	<input type="hidden" name="no" value="${data.NO}">
	<input type="hidden" name="page" id="page" value="${param.page}" /> <!-- 전 화면에서 넘어온 페이지 정보 -->
		<!-- 전 화면에서 넘어온 검색 정보 -->
	<input type="hidden" name="searchGbn"  id="searchGbn" value="${param.searchGbn}"/>
	<input type="hidden" name="searchTxt"  id="searchTxt" value="${param.searchTxt}"/>
	<!-- 전화면에서 넘어온 카테고리 번호 -->
	<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</form>
<div class="wrap">
<table class="board_detail_table">
	<tr>
		<th>카테고리</th>
		<td>${cateNm}</td>
	</tr>
	<tr>
		<th>번호</th>
		<td>${data.NO}</td>
	</tr>
	<tr>
		<th>제목</th>
		<td>${data.TITLE}</td>
	</tr>
	<tr>
		<th>작성자</th>
		<td>${data.MEM_NM}</td>
	</tr>
	<tr>
		<th>조회수</th>
		<td> ${data.HIT}</td>
	</tr>
	<tr>
		<th>작성일</th>
		<td> ${data.DT}</td>
	</tr>
	<tr>
		<th colspan="2">내용</th>
	</tr>
	<tr>
		<td class="con" colspan="2">${data.CON}</td>
	</tr>
	<c:if test="${!empty data.ATT}">
	<!-- fn:length(대상) : 대상 문자열의 길이나 배열, 리스트의 크기를 가져온다 -->
	<c:set var="fileLength" value="${fn:length(data.ATT)}"></c:set>
	<!-- fn:substring(값, 숫자1, 숫자2) : 값을 숫자1이상부터, 숫자2미만까지, 인덱스 기준으로 자른다. -->
	<c:set var="fileName" value="${fn:substring(data.ATT, 20, fileLength)}"></c:set>
	<tr>
		<th>첨부파일</th>
		<!-- download 없으면 이미지를 브라우저에 띄움, 파일을 안 받고 -->
		<!-- download="${fileName}" 옵션을 줘야 다운받을때도 파일명으로 받아짐 -->
		<td><a href="resouces/upload/${data.ATT}" download="${fileName}">${fileName}</a></td>
	</tr>
	</c:if>
</table>
	<div class="cmn_btn_ml float_right_btn" id="listBtn">목록</div>
	<c:if test="${sMemNo eq data.MEM_NO}">
		<div class="cmn_btn_ml float_right_btn" id="deleteBtn">삭제</div>
		<div class="cmn_btn_ml float_right_btn" id="updateBtn">수정</div>
	</c:if>
</div>
</body>

 

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;
}

.att {
	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("con", {
		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 () {
		// 기존 파일 내역 영역 제거
		$(".attOld").remove();
		// 기존 값 제거
		$("#att").val("");
		// 파일 선택 영역 제공 
		$(".att").show();
	});
	
	$("#updateBtn").on("click", function () {
		// CKEditor의 값 취득
		// CKEDITOR.instances[아이디] : CKEditor중 아이디가 같은 것을 찾겠다.
		//.getData() : 작성중인 내용을 취득하겠다.
		$("#con").val(CKEDITOR.instances['con'].getData());
		
		if($.trim($("#title").val()) == ""){
			makeAlert("알림","제목 입력하세요." , function () {
				$("#title").focus();
			})
		} else if($.trim($("#con").val()) == ""){
			makeAlert("알림","내용을 입력하세요." , function () {
				$("#con").focus();
			})
		} else {
			// 1. 파입업로드 -> 2. 업로드 파일명 취득 -> 3. 글 저장
			// 폼 객체 취득
			var form = $("#actionForm");
			// ajaxForm 적용
			form.ajaxForm({
				success: function (res) { // 데이터 주고 받기 성공시
					if(res.result == "SUCCESS"){ // 파일 전송 성공
						// 올라간 파일이 존재한다면, 첨부파일이 없을 수도 있으니 조건문 처리
						if(res.fileName.length > 0){
							$("#att").val(res.fileName[0]); // 올라간 파일명 보관		
						}
						// 3번 단계 글저장 시작, 기존테이터
						var params = $("#actionForm").serialize();
						
						$.ajax({
							url : "ATAction/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="ATDetail" id="backForm" method="post">
	<input type="hidden" name="no" value="${data.NO}" />
	<input type="hidden" name="page" value="${param.page}" />
	<input type="hidden" name="searchGbn" value="${param.searchGbn}"/>
	<input type="hidden" name="searchTxt" value="${param.searchTxt}"/>
	<input type="hidden" name="cateNo"value="${param.cateNo}"/>
</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}" />
	<!-- 전화면에서 넘어온 카테고리 번호 -->
	<input type="hidden" name="cateNo"value="${param.cateNo}"/>
		<table class="board_detail_table">
			<tr>
				<th>카테고리</th>
				<td>${cateNm}</td>
			</tr>
			<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="con" id="con">${data.CON}</textarea></th>
			</tr>
			<tr>
				<th>첨부파일</th>
				<c:choose>
					<c:when test="${empty data.ATT}">
						<!-- 파일이 없을때 -->
						<td>
							<input type="file" name="attFile" />
							<input type="hidden" name="att" id="att"/>
						</td>
					</c:when>
					<c:otherwise>
					<!-- 파일이 있을때 -->
						<td>
							<span class="attOld"> <!-- 기존 파일 -->
								<!-- fn:length(대상) : 대상 문자열의 길이나 배열, 리스트의 크기를 가져온다 -->
								<c:set var="fileLength" value="${fn:length(data.ATT)}"></c:set>
								<!-- fn:substring(값, 숫자1, 숫자2) : 값을 숫자1이상부터, 숫자2미만까지, 인덱스 기준으로 자른다. -->
								<c:set var="fileName" value="${fn:substring(data.ATT, 20, fileLength)}"></c:set>
								${fileName}
								<div class="cmn_btn_ml float_right_btn" id="fileDelBtn">파일삭제</div>
							</span>
							<span class="att"> <!-- 기존 파일 삭제 후 새 파일 용도 -->
								<input type="file" name="attFile" />
								<input type="hidden" name="att" id="att" value="${data.ATT}"/>
							</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>

 

ATController.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 ATController {
	@Autowired
	public IACDao iACDao;

	@Autowired
	public IPagingService ips;

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

		// 비동기가 되면 일단 아무것도 처음에 셋팅 X,
		// 페이지만 셋팅
		int page = 1;

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

		// 카테고리 목록 취득
		List<HashMap<String, String>> cate = iACDao.getList("cob.getCateAllList");

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

		return mav;
	}

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

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

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

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

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

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

		return mapper.writeValueAsString(model);
	}

	@RequestMapping(value = "/ATInsert")
	public ModelAndView aTInsert(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
		String cateNm = iACDao.getString("cob.getCate", params);

		mav.addObject("cateNm", cateNm);

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

		return mav;
	}

	@RequestMapping(value = "/ATAction/{gbn}", method = RequestMethod.POST, produces = "text/json;charset=UTF-8")
	@ResponseBody
	public String ATAction(@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("T.insertT", params);
				break;
			case "update":
				cnt = iACDao.update("T.updateT", params);
				break;
			case "delete":
				cnt = iACDao.update("T.deleteT", 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 = "/ATDetail")
	public ModelAndView aTDetail(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
		// 글번호 안 넘어왔을때 처리
		if (params.get("no") != null && params.get("no") != "") {
			// 조회수
			iACDao.update("T.updateTHit", params);
			HashMap<String, String> data = iACDao.getMap("T.getT", params);

			String cateNm = iACDao.getString("cob.getCate", params);

			mav.addObject("cateNm", cateNm);

			mav.addObject("data", data);

			mav.setViewName("testa/T/detail");
		} else {
			mav.setViewName("redirect:ATList");
		}

		return mav;
	}

	@RequestMapping(value = "/ATUpdate")
	public ModelAndView aTUpdate(@RequestParam HashMap<String, String> params, ModelAndView mav) throws Throwable {
		// 글번호 안 넘어왔을때 처리
		if (params.get("no") != null && params.get("no") != "") {
			HashMap<String, String> data = iACDao.getMap("T.getT", params);

			String cateNm = iACDao.getString("cob.getCate", params);

			mav.addObject("cateNm", cateNm);

			mav.addObject("data", data);

			mav.setViewName("testa/T/update");
		} else {
			mav.setViewName("redirect:ATList");
		}

		return mav;
	}

}

Cate_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="cob">
	<insert id="insertOb" parameterType="hashmap">
		INSERT INTO CATE(CATE_NO, CATE_NM) VALUES (CATE_SEQ.NEXTVAL, #{cateNm})
	</insert>
	<update id="updateOb" parameterType="hashmap">
		UPDATE CATE SET CATE_NM = #{cateNm}
		WHERE CATE_NO = #{no}
	</update>
	<update id="deleteOb" parameterType="hashmap">
		UPDATE CATE SET DEL = 0
		WHERE CATE_NO = #{no}
	</update>
	<select id="getObCnt" parameterType="hashmap" resultType="Integer">
		SELECT COUNT(*) AS CNT
			FROM CATE
		WHERE DEL = 1
		<if test="searchText != null and searchText != ''">
			<choose>
			 	<when test="searchGbn eq 0">
			 			AND CATE_NO = #{searchText} 
			 	</when>
				<when test="searchGbn eq 1">
			 			AND CATE_NM LIKE '%' || #{searchText} || '%'
			 	</when>
			</choose>
		</if>
	</select>
	<select id="getObList" parameterType="hashmap" resultType="hashmap">
		SELECT S.CATE_NO, S.CATE_NM
		FROM(SELECT CATE_NO, CATE_NM, 
		ROW_NUMBER() OVER(ORDER BY CATE_NO DESC, CATE_NM DESC) AS RNK
		FROM CATE
		 WHERE DEL = 1
	      <if test="searchText != null and searchText != ''">
				<choose>
				 	<when test="searchGbn eq 0">
				 			AND CATE_NO = #{searchText} 
				 	</when>
					<when test="searchGbn eq 1">

				 			AND CATE_NM LIKE '%' || #{searchText} || '%'
				 	</when>
				</choose>
			</if>
	      ) S
		WHERE S.RNK BETWEEN #{start} AND #{end}
	</select>
	
	<select id="getCateAllList" resultType="hashmap">
		SELECT CATE_NO, CATE_NM
		FROM CATE
		WHERE DEL = 1
	</select>
	
	<!-- 이름 취득용 -->
	<select id="getCate" parameterType="hashmap" resultType="String">
		SELECT CATE_NM
		FROM CATE
		WHERE DEL = 1
		AND CATE_NO = #{cateNo}
	</select>
	
	
</mapper>

 

총 수정한곳 7군데

728x90