Spring

12.16.(금) Spring Framework(32): 자료실 기능(6)

콜라든포비 2022. 12. 18. 23:01

글 수정

자료실의 글을 수정할 땐 업로드할때와 같이 파일에 대한 객체를 사용해야하므로 꽤나 복잡하다.

우선 컨트롤러 매핑부터 해보자.

컨트롤러 매핑

// 글 수정
@GetMapping("/data/dataEdit")
public ModelAndView dataEdit(int postno) {
	ModelAndView mav = new ModelAndView();
	
	mav.addObject("vo", service.dataView(postno));
	mav.setViewName("data/dataEdit");
	
	return mav;
}

얻어와야할 내용이 글 보기와 동일하기 때문에 이미 만들어 놓은 service를 이용했다.

뷰페이지 (form)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- attribute : vo -->
<style>
	#editForm>ul{
		overflow:auto;
	}
	#editForm>ul>li{
		float:left;
		padding:5px 0;
		width:10%;
	}
	#editForm>ul>li:nth-child(2n){
		width:90%;
	}
	#subject, #content{
		width:90%;
	}
	#content{
		height:200px;
	}
</style>
<title>자료실 수정</title>
<div class="container">
	<h1>자료 올리기</h1>
	<form method="post" action="/myapp/data/dataEditOk" enctype="multipart/form-data" id="editForm">
		<ul>
			<li>제목</li>
			<li><input type="text" name="subject" id="subject" value="${ vo.subject }"></li>
			<li>내용</li>
			<li>
				<textarea name="content" id="content">${ vo.content }</textarea>
			</li>
			<li>첨부파일</li>
			<li>
				<!-- 첫번째 첨부파일 -->
				${ vo.filename1 }
				<!-- 두번째 첨부파일 -->
				${ vo.filename2 }
			</li>
			<li><input type="submit" value="수정하기"></li>
		</ul>
	</form>
</div>

이제 이 단계까진 문제없다.


이제 첨부파일을 어떻게 고칠지 알아보자.

우선 이미 올려놓은 파일을 지우고 새로운 파일을 첨부할 수 있는 기능을 만들자.

누르면 파일을 지우는 X 기호를 첨부파일 옆에 뜨도록 만들었다.

<li>
	<!-- 첫번째 첨부파일 -->
	<div>${ vo.filename1 }&nbsp;&nbsp;&nbsp;&nbsp;<b class="del">X</b></div>
	<div><input type="hidden" name="filename" id="filename1"></div>
	<!-- 두번째 첨부파일 있을때-->
	<c:if test="${ vo.filename2!=null && vo.filename2!='' }">
		<div>${ vo.filename2 }&nbsp;&nbsp;&nbsp;&nbsp;<b class="del">X</b></div>
		<div><input type="hidden" name="filename" id="filename2"></div>
	</c:if>
	<!-- 두번째 첨부파일 없을때 -->
	<c:if test="${ vo.filename2==null || vo.filename2=='' }">
		<div><input type="file" name="filename" id="filename2"></div>
	</c:if>
</li>

이제 저 X를 누르면 기존 파일을 지우고, 새로 첨부파일을 고를 수 있도록 기능을 만들자.

X를 누르면 X의 부모태그인 div태그를 숨김과 동시에, 다음에 있는 input태그의 속성을 hidden에서 file로 바꾼다.

jQuery를 사용하면 가능하다.

<script>
	$(function(){
		// X를 눌러 기존 첨부파일은 제거하고, 새로운 파일을 선택할 수 있도록 해주는 이벤트
		$("#editForm b.del").click(function(){
			$(this).parent().css("display","none");	// 부모태그에 style="display:none" 추가
			// type="hidden" -> type="file"로 바꿔서 새로운 파일을 선택할 수 있도록 한다.
			$(this).parent().next().children().attr("type","file");	// 부모태그의 다음 태그의 자식태에 속성 type="file" 추가
		});
	});
</script>

여기서 숨겨버린 파일에 대한 정보가 필요하다. 이 글을 수정할때 첨부파일이 바뀌거나 없어지면, DB에서 수정을 해야하기 위함이다.

지워야할 파일에 대한 정보를 담아줄 input태그를 하나 더 만들어서, X를 누르면 해당 태그에 이름을 부여하자.

<li>
	<!-- 첫번째 첨부파일 -->
	<div>${ vo.filename1 }&nbsp;&nbsp;&nbsp;&nbsp;<b class="del">X</b></div>
	<div><input type="hidden" name="filename" id="filename1"></div>
	<input type="hidden" name value="${ vo.filename1 }">	<!-- 삭제한 파일에 대한 정보 -->
	<!-- 두번째 첨부파일 있을때-->
	<c:if test="${ vo.filename2!=null && vo.filename2!='' }">
		<div>${ vo.filename2 }&nbsp;&nbsp;&nbsp;&nbsp;<b class="del">X</b></div>
		<div><input type="hidden" name="filename" id="filename2"></div>
		<input type="hidden" name value="${ vo.filename2 }">
	</c:if>
	<!-- 두번째 첨부파일 없을때 -->
	<c:if test="${ vo.filename2==null || vo.filename2=='' }">
		<div><input type="file" name="filename" id="filename2"></div>
	</c:if>
</li>

그리고 jQuery에서 X를 누르면 이 태그들에게 name을 지어주면 된다.

<script>
	$(function(){
		// X를 눌러 기존 첨부파일은 제거하고, 새로운 파일을 선택할 수 있도록 해주는 이벤트
		$("#editForm b.del").click(function(){
			$(this).parent().css("display","none");	// 부모태그에 style="display:none" 추가
			// type="hidden" -> type="file"로 바꿔서 새로운 파일을 선택할 수 있도록 한다.
			$(this).parent().next().children().attr("type","file");	// 부모태그의 다음 태그의 자식태그에 속성 type="file" 추가
			$(this).parent().next().next().attr("name","delFile");	// 부모태그의 다음다음태그에 속성 name="delFile" 추가
		});
	});
</script>

X를 누르면 부모태그의 다음다음태그에 속성 name="delFile"을 추가하도록 했다.

DataVO로 넘어와서 삭제할 파일목록에 대한 변수(delFile)를 만들어주자.

package com.poby.myapp.vo;

import java.util.List;

public class DataVO {
	private int postno;
	private String username;
	private String subject;
	private String content;
	private int hitcount;
	private String regdate;
	private String filename1;
	private String filename2;
	
	// 삭제할 파일 목록
	// private String[] delFile;
	private List<String> delFile;
}

현재 첨부파일이 몇 개 있는지에 대한 정보도 필요하다. 이 정보가 필요한 곳은 뷰페이지이므로, 컨트롤러에서 구해서 넘겨주자.

// 글 수정
@GetMapping("/data/dataEdit")
public ModelAndView dataEdit(int postno) {
	ModelAndView mav = new ModelAndView();
	DataVO vo = service.dataView(postno);
	
	// 첨부파일 수
	int filecnt = 0;
	if(vo.getFilename1()!=null) filecnt++;
	if(vo.getFilename2()!=null) filecnt++;
	
	mav.addObject("filecnt", filecnt);
	mav.addObject("vo", vo);
	mav.setViewName("data/dataEdit");
	
	return mav;
}

다시 뷰페이지로 넘어와서 jQuery에 기능을 추가하자.

<script>
	var filecnt = ${ filecnt };
	$(function(){
		// X를 눌러 기존 첨부파일은 제거하고, 새로운 파일을 선택할 수 있도록 해주는 이벤트
		$("#editForm b.del").click(function(){
			$(this).parent().css("display","none");	// 부모태그에 style="display:none" 추가
			// type="hidden" -> type="file"로 바꿔서 새로운 파일을 선택할 수 있도록 한다
			$(this).parent().next().children().attr("type","file");	// 부모태그의 다음 태그의 자식태그에 속성 type="file" 추가
			$(this).parent().next().next().attr("name","delFile");	// 부모태그의 다음다음태그에 속성 name="delFile" 추가
			
			// 첨부파일의 개수를 감소시킨다
			filecnt--;
		});
	});
</script>

X를 눌렀을때 첨부파일의 개수를 나타내는 변수 filecnt도 감소시킨다.


유효성 검사

<script>
	var filecnt = ${ filecnt };
	$(function(){
		// X를 눌러 기존 첨부파일은 제거하고, 새로운 파일을 선택할 수 있도록 해주는 이벤트
		$("#editForm b.del").click(function(){
			$(this).parent().css("display","none");	// 부모태그에 style="display:none" 추가
			// type="hidden" -> type="file"로 바꿔서 새로운 파일을 선택할 수 있도록 한다
			$(this).parent().next().children().attr("type","file");	// 부모태그의 다음 태그의 자식태그에 속성 type="file" 추가
			$(this).parent().next().next().attr("name","delFile");	// 부모태그의 다음다음태그에 속성 name="delFile" 추가
			
			// 첨부파일의 개수를 감소시킨다
			filecnt--;
		});
		
		// form 유효성 검사
		$("#editForm").submit(function(){
			// 제목
			if($("#subject").val()==""){
				alert("제목을 입력하세요.");
				return false;
			}
			
			// 첨부파일 개수
			if($("#filename1").val()!="") filecnt++;
			if($("#filename2").val()!="") filecnt++;
			if(filecnt<1){
				alert("첨부파일은 최소 1개 이상이여야 합니다.");
				return false;
			}
			return true;
		});
	});
</script>

이제 수정된 파일로 기존에 업로드된 파일을 교체하는 기능을 구현해보자.