/** * 드래그앤드랍 파일 업로드를 활용한 파일 업로더 * $('input hidden element').dragFileUploader(options, [callback]) */ ; (function($) { function uploader(input, options, callback) { const uploader = { input : null // 옵션 , options : { 'allowedTypes' : ['ppt', 'pptx', 'hwp', 'xls', 'xlsx', 'doc', 'docx', 'png', 'jpg', 'jpeg', 'gif', 'pdf'] , 'maxSize' : 10 , 'maxCount' : 5 , 'useBtnDelete' : true , 'useDragDrop' : true , 'useClick' : true , 'wrapSelector' : '#file_box_wrap' , 'viewType' : 'file' // img, file, popup , 'viewSelector' : null } // 초기화 , init : function() { // 드래그앤드랍 초기화 if (this.options.useDragDrop) { this.initDropZone(); } // 클릭 초기화 if (this.options.useClick) { this.initClick(); } // 초기 데이터 셋팅 if (this.input.val() != '') { var $viewSelector = $(this.options.wrapSelector + " .file_list"); this.initView('popup', $viewSelector); } return this; } // 초기 데이터 셋팅 , initView : function(type, selector) { let fileId = this.input.val(); let $selector = selector == null ? $(uploader.options.viewSelector) : $(selector); // 기존 DOM 삭제 $selector.empty(); if (fileId == '') { return this; } var params = { 'fileId' : fileId } $.post(CONTEXT_PATH + '/fileList/selectJson.do', params, function(data) { if (data.sttus == 'success') { let files = data.result; $.each(files, function(i, file) { var param = { 'name' : file.originFileNm , 'size' : file.fileSize } var $file = uploader.createDom(param, type); $selector.append($file); // 이벤트 추가(다운로드, 삭제, 데이터 셋팅) uploader.fncFileTrigger($file, file); }); } else { alert('파일을 불러오는 중 오류가 발생하였습니다.'); } }); return this; } // 클릭 초기화 , initClick : function() { var $selector = $(this.options.wrapSelector); var $dropZone = $selector.find('.dropZone'); var $fileInput = $('', {'type': 'file', 'multiple' : 'multiple', 'class' : 'blind'}); // 파일 변경 이벤트 $fileInput.on('change', function() { var files = this.files; // 업로드 함수 uploader.fncFileUpload(files); }); // 드랍존 다음에 파일 추가(드랍존 안에 추가 하면 중복 클릭 이벤트 발생) $dropZone.after($fileInput); $dropZone.on('click', function() { $fileInput.trigger('click'); }); } // 드래그앤드랍 초기화 , initDropZone : function() { var $selector = $(this.options.wrapSelector); var $dropZone = $selector.find('.dropZone'); $('html') .on('dragover', function(e) { e.preventDefault(); e.stopPropagation(); }) .on('drop', function(e) { e.preventDefault(); e.stopPropagation(); }); $dropZone .on('dragenter', function(e) { e.preventDefault(); e.stopPropagation(); $(this).prop('style', 'border:1px dashed #0a52ad;'); $(this).find('p').prop('style', 'opacity:.8;'); }) .on('dragleave', function(e) { $(this).prop('style', null); $(this).find('p').prop('style', null); }) .on('dragover', function(e) { e.preventDefault(); e.stopPropagation(); }) .on('drop', function(e) { e.preventDefault(); e.stopPropagation(); var files = e.originalEvent.dataTransfer.files; // 업로드 함수 uploader.fncFileUpload(files); }); } // 파일 목록 데이터 반환 , fncGetData : function(name) { var $selector = $(this.options.wrapSelector); var arrData = new Array(); $selector.find('.file_list li').each(function(i) { if (name != null && name != '') { arrData.push($(this).data('result')[name]); } else { arrData.push($(this).data('result')); } }); return arrData; } // 확인(반환) 이벤트 , fncReturn : function() { var list = uploader.fncGetData('fileId'); return list.join(','); } // 콜백 함수 필요시 추가 , callback : function() { } // 파일 업로드 , fncFileUpload : function(files) { $.each(files, function(i, file) { var fd = new FormData(); fd.append('file', file); // 확장자 및 용량, 갯수 체크 if (!uploader.fncValidate(uploader.options, file)) { return true; }; // 업로드 UI 생성 var $file = uploader.createDom(file, 'popup'); var $selector = $(uploader.options.wrapSelector); $selector.find('.file_list').append($file); $.ajax({ type : 'post', url : CONTEXT_PATH + '/uploadFile.do', data : fd, processData : false, contentType : false, beforeSend : function() { }, complete : function() { }, success : function(data) { if (data.sttus == 'success') { var result = data.result; // 완료 처리 var $filename = $file.find('.filename'); $filename.append('업로드 성공 아이콘'); // 이벤트 추가(다운로드, 삭제, 데이터 셋팅) uploader.fncFileTrigger($file, result); } else { alert(file.name + " 파일 업로드에 실패하였습니다."); $file.remove(); } }, error : function(error) { alert("파일 업로드에 실패하였습니다."); $file.remove(); }, xhr : function() { // 프로그래스 var xhr = $.ajaxSettings.xhr(); // 업로드 중 프로그래스바 표시 xhr.upload.onprogress = function(e) { var per = e. loaded * 100 / e.total; // 프로그래스바 이동 var $bar = $file.find('.bar'); $bar.prop('style', 'width: ' + per + '%'); if (per === 100) { $bar.addClass('blind'); } } return xhr; }, }); }); } //파일 이벤트(다운로드, 삭제, 데이터 셋팅) , fncFileTrigger : function(file, result) { // 데이터 셋팅 file.data('result', result); // 이미지뷰 file.find('img.imgThumb').prop('src', CONTEXT_PATH + result.link); // 다운로드 버튼 이벤트 file.find('.btn_filedown').on('click', function() { location.href = CONTEXT_PATH + result.link; }); // 삭제 버튼 이벤트 file.find('.btn_delete').on('click', function() { file.remove(); // 삭제 후 포커스 $('#file_box_wrap').find('a,input,button').eq(0).focus(); }); } //확장자 체크 및 용량 체크, 파일 첨부 갯수 , fncValidate : function(options, file) { var isTrue = true; if (options.allowedTypes.indexOf('*') == -1) { var ext = file.name.split('.').pop().toLowerCase(); if( $.inArray(ext, options.allowedTypes) == -1 ) { alert(file.name + ' 파일은 허용되지 않은 확장자입니다.\n' + options.allowedTypes.join(', ') + ' 확장자 만 가능합니다.'); return false; } } if (options.maxSize > -1) { var fileSize = file.size; var maxSize = options.maxSize * 1024 * 1024; if( fileSize > maxSize ) { alert('파일 사이즈는 ' + uploader.fileSizeConvert(maxSize) + '이내로 등록 가능합니다.'); return false; } } var $selector = $(options.wrapSelector); var fileListCnt = $selector.find('.file_list li').length; var maxCount = options.maxCount; if (fileListCnt >= maxCount) { alert('파일 첨부 가능 갯수는 총 ' + maxCount + '개 입니다.'); return false; } return isTrue; } //파일 사이즈 형식 변경 , fileSizeConvert : function(size) { var fileSize = size; if (fileSize / 1024 >= 1024) { fileSize = (fileSize / (1024 * 1024)).toFixed(1) + "MB"; } else { fileSize = (fileSize / 1024).toFixed(1) + "KB"; } return fileSize; } //파일 확장자별 아이콘 , fileExtIcon : function(ext) { var fileIcon = 'file_reg'; switch (ext) { case 'pdf': fileIcon = 'file_pdf'; break; case 'ppt': fileIcon = 'file_ppt'; break; case 'pptx': fileIcon = 'file_ppt'; break; case 'xls': fileIcon = 'file_excel'; break; case 'xlsx': fileIcon = 'file_excel'; break; case 'doc': fileIcon = 'file_word'; break; case 'docx': fileIcon = 'file_word'; break; case 'hwp': fileIcon = 'file_hwp'; break; case 'png': fileIcon = 'file_img'; break; case 'jpg': fileIcon = 'file_img'; break; case 'jpeg': fileIcon = 'file_img'; break; case 'gif': fileIcon = 'file_img'; break; case 'bmp': fileIcon = 'file_img'; break; case 'zip': fileIcon = 'file_zip'; break; case '7z': fileIcon = 'file_zip'; break; default: fileIcon = 'file_reg'; } return fileIcon; } // DOM생성 , createDom : function(file, type) { var name = file.name; var size = uploader.fileSizeConvert(file.size); var ext = name.split('.').pop().toLowerCase(); var dom; switch (type) { case 'popup': dom = '
  • ' + '

    ' + name + ' [' + size + ']

    ' + '
    ' + '' + '' + '
    ' + '
    업로드상태' + '
    ' + '
    ' + '
  • '; break; case 'img': dom = '
  • ' + '첨부 이미지' + '
    ' + '' + '
    ' + '
  • '; break; default: dom = '
  • ' + '
    ' + '

    ' + name + '

    ' + '' + '
    ' + '
  • '; break; } return $(dom); } // 파일 업로더 팝업 열기(button selector) , fncOpenPopup : function(selector) { var params = { 'fileId' : uploader.input.val() } $(selector).on('click', function() { fn_popupOpen(CONTEXT_PATH + "/uploadFile/popup.do", 500, 500, params, 'Y', function(popupId) { // 초기화 uploader.init(); // 확인 이벤트 $('#' + popupId).find('.btn_saveFile').on('click', function() { // 히든 값 셋팅 uploader.input.val(uploader.fncReturn()); var $viewSelector = $(uploader.options.viewSelector); var viewType = uploader.options.viewType; uploader.initView(viewType, $viewSelector); if (typeof uploader.callback == 'function') { uploader.callback(uploader); } }); }); }); return this; } } // input hidden uploader.input = $(input); // 옵션 if (options != null) { uploader.options = $.extend({}, uploader.options, options); } // 콜백 함수 if (typeof callback == 'function') { uploader.callback = callback; } return uploader; } $.fn.dragFileUploader = function(options, callback) { var fileUploader = new uploader(this, options, callback); return fileUploader; } })(jQuery);