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>