12.16.(금) Spring Framework(32): 자료실 기능(6)
글 수정
자료실의 글을 수정할 땐 업로드할때와 같이 파일에 대한 객체를 사용해야하므로 꽤나 복잡하다.
우선 컨트롤러 매핑부터 해보자.
컨트롤러 매핑
// 글 수정
@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 } <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 } <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 } <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 } <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>
이제 수정된 파일로 기존에 업로드된 파일을 교체하는 기능을 구현해보자.