jquery-file-upload

최근의 작업 중에 대용량 파일을 업로드할 필요성이 있어 관련 플러그인을 서치 후 사용하게 된 jQuery File Upload 이다. 큰 파일의 경우 여러 개의 파일로 쪼개서 업로드 하기 때문에 서버 용량이 허용하는 한 파일을 업로드할 수 있다. 중간에 오류가 나지 않는다는 전제하에서 말이다. 그리고 파일 업로드가 ajax 로 처리 되기 때문에 시각적으로도 좋은 점이 있다.

파일 업로드가 필요한 페이지에 아래와 같이 관련 코드를 추가했다.

/css/jquery-file-upload/jquery.fileupload.css
/css/jquery-file-upload/jquery.fileupload-ui.css
/js/jquery-file-upload/vendor/jquery.ui.widget.js
/js/jquery-file-upload/jquery.iframe-transport.js
/js/jquery-file-upload/jquery.fileupload.js
/js/jquery-file-upload/jquery.fileupload-process.js
Copy

jQuery File Upload 전체 소스를 보면 위 파일 외에 다른 css, js 파일도 있지만 위의 파일만 사용해도 문제는 없다. 디자인 요소를 과감하게 빼버린 탓에.. 개발자가 디자인까지 신경쓰면.. 일이 안되니까.. ^^; 그리고 파일 업로드 페이지는 아래와 같은 마크업 구조를 가진다.

<input type="file" name="files" id="file_software" class="file-upload" data-url="http://example.com/file/upload" data-form-data='{"extra": "software"}'>
<ul class="file-list list-unstyled mb-0"></ul>
Copy

위 마크업 중 data-form-data 는 파일 업로드 때 추가적인 정보를 처리하기 위한 것으로 없어도 되는 부분이다. 그리고 디자인 부분은 부트스트랩을 사용했기 때문에 관련 css 클래스 등이 추가되어 있다. 부트스트랩을 사용하는 게 내게 최선의 방법이다. 이제 아래와 같은 코드를 추가해서 jQuery File Upload 플러그인 사용 설정을 해줘야 한다. 기본 코드 외에 몇 가지 필요한 내용이 있어 코드를 추가한 부분이 있다.

<?php
$maxUploadFileSize = getUploadMaxFileSize();
$script = <<<SCRIPT
<script>
jQuery(function() {
    jQuery(".file-upload").fileupload({
        dataType: "json",
        maxChunkSize: $maxUploadFileSize,
        sequentialUploads: false,
        add: function(e, data) {
            var maxFileCount = parseInt($(this).data("maxfilecount"));
            if (isNaN(maxFileCount))
                maxFileCount = 1;
            console.log(maxFileCount);
            var \$t = $(this);
            var \$w = \$t.closest("div");
            var \$li = \$w.find("ul.file-list li");
            if (\$li.length >= maxFileCount) {
                var txt = \$w.find("label").text();
                alert("업로드된 " + txt + " 파일이 있습니다. 기존 파일을 삭제하신 후 새로 업로드해 주십시오.");
                return false;
            }
            data.context = $('<li class="file my-1 row"></li>')
                .append(jQuery('<div class="file-name col-md-8 text-muted"></div>').text(data.files[0].name))
                .append('<div class="progress col-md-3 my-auto px-0"><div class="progress-bar progress-bar-striped bg-info" role="progressbar"></div></div>')
                .append('<div class="del-button col-md-1"></div>')
                .appendTo($(this).siblings(".file-list"));
            data.submit();
        },
        progress: function(e, data) {
            var progress = parseInt((data.loaded / data.total) * 100, 10);
            data.context.find(".progress-bar").css("width", progress + "%");
        },
        done: function(e, data) {
            var res = data.result.files[0];
            var val = res.path;
            var url = res.deleteUrl;
            if (res.error !== "") {
                data.context.remove();
                alert(res.error);
                return false;
            }
            jQuery(this.form)
                .find("input[type=hidden]:last")
                .after('<input type="hidden" name="upload[]" value="' + val + '">');
            data.context
                .find(".file-name")
                .removeClass("text-muted")
                .append(' <span class="badge badge-success"><i class="fas fa-check"></i></span>')
                .end()
                .find(".del-button")
                .append('<button type="button" class="btn btn-sm btn-danger upload-delete" data-val="' + val + '" data-type="DELETE" data-url="' + url + '"><i class="far fa-trash-alt"></i></button>');
            jQuery(this).blur();
        }
    });
    jQuery(document).on("click", ".upload-delete", function(e) {
        var \$t   = jQuery(this);
        var val  = \$t.data("val");
        var url  = \$t.data("url");
        var type = \$t.data("type");
        jQuery.ajax({
            url: url,
            type: type,
            success: function(data) {
                \$t.closest("li").remove();
                jQuery("input[name='upload[]']").each(function(i) {
                    var \$el = jQuery(this);
                    if (\$el.val() == val)
                        \$el.remove();
                });
            },
            error: function(request, status, error) {
                console.log("code:"+request.status+"\\n"+"message:"+request.responseText+"\\n"+"error:"+error);
            },
            dataType: "JSON"
        });
    });
    jQuery(document).on("click", ".file-delete", function(e) {
        if(!confirm("파일을 삭제하시겠습니까?"))
            return false;
        var \$t  = jQuery(this);
        var act = \$t.data("act");
        var key = \$t.data("key");
        var no  = \$t.data("no");
        var token = setTokenValue("", "admin");
        jQuery.ajax({
            url: "./filedelete.php",
            data: {act: act, key: key, no: no, token: token},
            success: function(data) {
                if (data.error != "") {
                    alert(data.error);
                    return false;
                }
                \$t.closest("li").remove();
            },
            error: function(request, status, error) {
                console.log("code:"+request.status+"\\n"+"message:"+request.responseText+"\\n"+"error:"+error);
            },
            dataType: "JSON"
        });
    });
});
</script>
SCRIPT;
echo $script;
?>
Copy

스크립트 부분만 포스팅하면 되는데.. 코드를 작업한 코드에서 바로 가져오다 보니 php 형태의 코드가 되고 말았다. 실제 사용에서는 적절하게 수정되어야 한다. 위 코드를 보면 파일 업로드 개수 체크하는 부분과 업로드 후 파일이 표시되는 부분을 커스터마이징하기 위한 내용이 주를 이룬다. 실제로 파일 업로드 후 표시되는 화면은 아래와 같다.

디자인적은 측면은 전문이 아니니까.. 잘 수정해서 사용하면 된다. 그리고 코드 중 업로드 파일을 삭제하는 코드가 있는데 이것은 두 가지로 분리해서 처리했다. 신규 글쓰기 등에서는 임시로 업로드된 파일을 삭제해야 하기 때문에 jQuery(document).on("click", ".upload-delete", function(e) { 에서 처리가 되도록 되어있고 글쓰기 완료 후 업로드된 파일은 위치를 변경해서 저장하도록 했기 때문에 jQuery(document).on("click", ".file-delete", function(e) { 에서 처리가 된다. 파일 업로드 처리 및 DB 처리 코드는 jQuery File Upload 에서 제공하는 UploadHandler.php 파일을 참고해서 처리했다.

0
0
이 글을 페이스북으로 퍼가기 이 글을 트위터로 퍼가기 이 글을 카카오스토리로 퍼가기 이 글을 밴드로 퍼가기

HTML/CSS/기타

번호 제목 글쓴이 날짜 조회수
46 JS 글자수 체크(공백포함, 제외) 및 언어 옵션 설정 관리자 09-02 1,318
45 web chart - 실시간 차트 관리자 07-25 1,349
44 비동기 프로그래밍 관리자 07-25 1,310
43 table thead 고정과 tbody 스크롤 관리자 07-23 1,362
42 datepicker 사용하여 공휴일 직접 지정하기 관리자 06-11 1,427
41 Dropzone - 이미지 & 파일 업로드 (드래그 앤 드롭) 라이브러리 관리자 03-06 1,585
40 JSPDF 사용법(Javascript pdf) 관리자 03-04 1,863
39 FullCalendar(풀캘린더) 어거지 사용법 관리자 01-25 1,775
38 JQUERY - id가 여러개인데 한번에 찾고 싶을때! ${} 관리자 12-28 1,613
37 [CSS] 가로 스크롤 구현하기 관리자 12-27 1,749
36 JCROP을 이용한 업로드한 크롭( CROP ) 하기 관리자 12-27 1,713
35 제이쿼리 - 모달 다이아로그 및 여러 알림창들 관리자 12-21 1,439
34 Javascript/jQuery 이미지 회전 돋보기 관리자 11-07 1,824
33 Resolving the Issue of Fakepath in JavaScript 관리자 10-26 1,486
32 div 및 요소 화면 중앙에 위치시키기 관리자 10-21 1,513
31 [Jquery] 체크박스 전체 체크 , 해제 하는 방법 관리자 10-19 1,525
30 display 스타일 속성 사용하여 행 숨기기/보이기 관리자 09-16 1,932
29 자주 사용하는 비주얼 스튜디오 코드(Visual Studio Code, VSC, vscode) 단축키 정리 관리자 09-14 2,007
28 div 2개 나란히 정렬하는 방법 관리자 09-09 1,729
27 HTML, CSS - 헤더컬럼 고정형 table 구성하기 관리자 09-06 1,562