드래그 앤 드롭 파일 업로드
jquery 를 활용하여 드래그 앤 드롭 멀티 파일 업로드 기능을 구현해 보자
요즘 홈페이지들을 보면 파일을 업로드 할 때 예전처럼 파일탐색창에서 선택하여 업로드 할수도 있지만
컴퓨터에 있는 파일을 마우스로 드래그해서 브라우저에 드랍하면 파일이 업로드 되는 기능을 자주 만날 수 있다.
구현하는 방식은 여러가지가 있을 거라고 생각이 된다.
본 포스팅에서는 jquery 를 활용하여 드래그 앤 드롭 기능을 구현해 보자.
설명 :
jquery 의 드롭 이벤트 dragenter, dragleave, dragover, drop 을 파일이 드롭될 특정 영역(태그)에 설정한다.
dragenter : 드래그 요소가 특정 영역에 들어갔을 경우 호출
dragleave : 드래그 요소가 특정 영역에서 벗어났을 경우 호출
dragover : 드래그 요소가 특정 영역에 있을 경우 호출
drop : 드래그 요소가 드롭되었을 경우 호출
위 4개의 이벤트 중 파일이 드롭되었을 경우에 drop 이벤트가 호출되며
이때 파일 Object를 javascript 영역에서 가지고 있다가
ajax를 활용하여 비동기 방식으로 전송하면 된다.
당연히 jquery 를 import 한 후 사용하여야 한다.
본 포스팅에서의 소스 설명은 소스 내부의 주석으로 대체한다.
기본적으로 파일 사이즈 비교 정도는 작성되어 있으나
실제로 사용할 경우에는 파일의 유무, 유형, 사이즈 등을 더 디테일하게 검사할 필요가 있다.
<!DOCTYPE>
<HTML>
<BODY>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
// 파일 리스트 번호
var fileIndex = 0;
// 등록할 전체 파일 사이즈
var totalFileSize = 0;
// 파일 리스트
var fileList = new Array();
// 파일 사이즈 리스트
var fileSizeList = new Array();
// 등록 가능한 파일 사이즈 MB
var uploadSize = 50;
// 등록 가능한 총 파일 사이즈 MB
var maxUploadSize = 500;
$(function (){
// 파일 드롭 다운
fileDropDown();
});
// 파일 드롭 다운
function fileDropDown(){
var dropZone = $("#dropZone");
//Drag기능
dropZone.on('dragenter',function(e){
e.stopPropagation();
e.preventDefault();
// 드롭다운 영역 css
dropZone.css('background-color','#E3F2FC');
});
dropZone.on('dragleave',function(e){
e.stopPropagation();
e.preventDefault();
// 드롭다운 영역 css
dropZone.css('background-color','#FFFFFF');
});
dropZone.on('dragover',function(e){
e.stopPropagation();
e.preventDefault();
// 드롭다운 영역 css
dropZone.css('background-color','#E3F2FC');
});
dropZone.on('drop',function(e){
e.preventDefault();
// 드롭다운 영역 css
dropZone.css('background-color','#FFFFFF');
var files = e.originalEvent.dataTransfer.files;
if(files != null){
if(files.length < 1){
alert("폴더 업로드 불가");
return;
}
selectFile(files)
}else{
alert("ERROR");
}
});
}
// 파일 선택시
function selectFile(fileObject){
var files = null;
if(fileObject != null){
// 파일 Drag 이용하여 등록시
files = fileObject;
}else{
// 직접 파일 등록시
files = $('#multipaartFileList_' + fileIndex)[0].files;
}
// 다중파일 등록
if(files != null){
for(var i = 0; i < files.length; i++){
// 파일 이름
var fileName = files[i].name;
var fileNameArr = fileName.split("\.");
// 확장자
var ext = fileNameArr[fileNameArr.length - 1];
// 파일 사이즈(단위 :MB)
var fileSize = files[i].size / 1024 / 1024;
if($.inArray(ext, ['exe', 'bat', 'sh', 'java', 'jsp', 'html', 'js', 'css', 'xml']) >= 0){
// 확장자 체크
alert("등록 불가 확장자");
break;
}else if(fileSize > uploadSize){
// 파일 사이즈 체크
alert("용량 초과\n업로드 가능 용량 : " + uploadSize + " MB");
break;
}else{
// 전체 파일 사이즈
totalFileSize += fileSize;
// 파일 배열에 넣기
fileList[fileIndex] = files[i];
// 파일 사이즈 배열에 넣기
fileSizeList[fileIndex] = fileSize;
// 업로드 파일 목록 생성
addFileList(fileIndex, fileName, fileSize);
// 파일 번호 증가
fileIndex++;
}
}
}else{
alert("ERROR");
}
}
// 업로드 파일 목록 생성
function addFileList(fIndex, fileName, fileSize){
var html = "";
html += "<tr id='fileTr_" + fIndex + "'>";
html += " <td class='left' >";
html += fileName + " / " + fileSize + "MB " + "<a href='#' onclick='deleteFile(" + fIndex + "); return false;' class='btn small bg_02'>삭제</a>"
html += " </td>"
html += "</tr>"
$('#fileTableTbody').append(html);
}
// 업로드 파일 삭제
function deleteFile(fIndex){
// 전체 파일 사이즈 수정
totalFileSize -= fileSizeList[fIndex];
// 파일 배열에서 삭제
delete fileList[fIndex];
// 파일 사이즈 배열 삭제
delete fileSizeList[fIndex];
// 업로드 파일 테이블 목록에서 삭제
$("#fileTr_" + fIndex).remove();
}
// 파일 등록
function uploadFile(){
// 등록할 파일 리스트
var uploadFileList = Object.keys(fileList);
// 파일이 있는지 체크
if(uploadFileList.length == 0){
// 파일등록 경고창
alert("파일이 없습니다.");
return;
}
// 용량을 500MB를 넘을 경우 업로드 불가
if(totalFileSize > maxUploadSize){
// 파일 사이즈 초과 경고창
alert("총 용량 초과\n총 업로드 가능 용량 : " + maxUploadSize + " MB");
return;
}
if(confirm("등록 하시겠습니까?")){
// 등록할 파일 리스트를 formData로 데이터 입력
var form = $('#uploadForm');
var formData = new FormData(form);
for(var i = 0; i < uploadFileList.length; i++){
formData.append('files', fileList[uploadFileList[i]]);
}
$.ajax({
url:"업로드 경로",
data:formData,
type:'POST',
enctype:'multipart/form-data',
processData:false,
contentType:false,
dataType:'json',
cache:false,
success:function(result){
if(result.data.length > 0){
alert("성공");
location.reload();
}else{
alert("실패");
location.reload();
}
}
});
}
}
</script>
<form name="uploadForm" id="uploadForm" enctype="multipart/form-data" method="post">
<table class="table" width="100%" border="1px">
<tbody id="fileTableTbody">
<tr>
<td id="dropZone">
파일을 드래그 하세요
</td>
</tr>
</tbody>
</table>
</form>
<a href="#" onclick="uploadFile(); return false;" class="btn bg_01">파일 업로드</a>
</BODY>
</HTML>