오래전 개인적으로 프로젝트를 수주받아 일을 하던차.
이미지 업로드를 해야하는데, drag & drop 기능을 넣어 달란다.
"아니 그게 active-x 없이 되는 거야?"
"몰라. 너가 알아서해"
이러던 와중 찾아보니 html5에서 drag&drop이 되더라.
그래서 이걸 input file element를 이용해 동기화해서 이용하려고 해보니.
input file은 보안 문제상 javascript에서 set value가 불가능하다고. ㅠ
하긴 생각해보면 아무파일이나 local에서 읽어다가 막 올릴 수 있겠지.
인증서도 막 올릴수 있겠지. ㅠ
근데 이런 문제는 css로 해결할 수 있다니.
얼마전부터 css를 하다보니 참 새삼 위대함을 느낀다.
일단 JQGRID를 이용해서 해당 그리드에 드랍을 하면,
파일 정보를 읽어서 그리드에 표시하고 저장버튼을 눌러 저장을 할 수 있는 형식으로 만들었다.
물론 여기까지 오는데 꾀 많은 템플릿? 데모? 를 만들었다.
그리드 부분을 아래처럼 div로 감싸고 droparea란 id로 지정을 했다.
<div style="float: left;" id="droparea"> <table id="theGrid01"></table> <table id="thePager01"></table> </div> |
그리고 드래그 엔터시와 아웃시 살짜쿵 스타일 변화를 주었다.
$('#droparea').on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); $(this).css('border', '2px dotted #0B85A1'); }); $('#droparea').on('dragleave', function (e) { e.stopPropagation(); e.preventDefault(); $(this).css('border', ''); }); |
그리고 실제 파일 드랍시 발생하는 부분이다.
$('#droparea').on('drop', function (e){ $(this).css('border', ''); e.preventDefault(); var files = e.originalEvent.dataTransfer.files; handleFileUpload(files); }); |
위에서 보다시피 이벤트에서 파일을 얻어와 그걸 handleFileUpload에 넘긴다.
자 그럼 그 내용이 뭔지 보자.
// 소스 내용 자체는 참 쉽다. var fd = new FormData(); // 일단 FormData를 local변수로 하나 생성하고 function handleFileUpload(files,obj) { fd = new FormData(); // FormData를 초기화 하는 이유는 드랍시마다 초기화 하려고.. // 그리드도 초기화 $("#theGrid01").jqGrid("clearGridData", true).trigger("reloadGrid");
// 드랍된 파일이 몇개일까.. for (var i = 0; i < files.length; i++) { // fd에 파일을 추가한다. fd.append('file_'+i, files[i]); var grid = $("#theGrid01"); var rowId = grid.jqGrid('getGridParam', 'reccount'); rowId++; rowId = rowId + ""; // 파일 사이즈를 구해서 var sizeStr=""; var sizeKB = files[i].size/1024; if(parseInt(sizeKB) > 1024) { var sizeMB = sizeKB/1024; sizeStr = sizeMB.toFixed(2)+" MB"; } else { sizeStr = sizeKB.toFixed(2)+" KB"; } var parameters = { rowID : rowId, // 초기 데이터를 넣고 initdata : {"FILE_NAME":files[i].name,"FILE_SIZE":sizeStr}, position : "last", useDefValues : false, useFormatter : false, addRowParams : { extraparam : {}, keys : true } } // 그리드에 row를 추가 grid.jqGrid('addRow', parameters); grid.jqGrid('setCell', rowId, "ST", gv_insert, ""); grid.jqGrid('setCell', rowId, "AT", "I"); } } |
위 처럼 하면 전송할 폼데이터 및 그리드에 해당 파일 정보가 쓰인다.
마지막으로 저장 버튼 누를시 이벤트는
function txcall(txid) { var url = ""; var mydata = ""; switch (txid) { case "SAVE": url = "호출경로"; mydata = fd; // 아까 위에서 생성한 폼데이터 break; } transactionFile(txid, url, mydata, "txcallback"); } |
transactionFIle은 jquery의 ajax를 이용해서 만든 함수다.
결국 그냥 ajax로 post방식으로 서버로 전송하는거다.
위 내용은 php로 했고, 서버사이드프로그램은 뭘 해도 상관없을듯 하다?...
추가적으로 끄적이자면. 큰 용량의 파일을 업로드시. 서버에 저장공간이 남아돈다면 모를까.
적당한 이미지로 보여주는것이 좋다.
PHP에서는...
thumb.php라는 오픈소스가 있는데, 이것을 이용해서 이미지를 사이즈를 작게 만들어서 저장하는 것도 방법이라면 방법이다.
드래그앤 드랍 참조 1 : http://hayageek.com/drag-and-drop-file-upload-jquery/