Logicky Blog

Logickyの開発ブログです

HTML5 File API デスクトップからブラウザにファイルをドロップしてアップロード

デスクトップからブラウザにファイルをドロップできるようにしたい。

参考 Reading files in JavaScript using the File APIs Drag and DropとFile APIを試す はまちーのにっき。

File APIと、FormDataというのを使った。ちょっとごちゃごちゃしてるけど、dorpクラスにdorpされたファイルを、順番にupload関数に渡してアップロードしている。cakePHPで受け取ってFileBinderで保存しましたが、FormData使ってファイルを渡すと、$this->request->params['form']に入っていた。dropされたらウインドウの下のに、ボックスが現れて、アップロード中のファイル名が表示されて、アップロード成功したら青くなって、失敗したら赤くなって、完了したらフェードアウトしてる様。$.Deferred()は、終わるまで次の処理を待たせたりできるやつらしいので、使ってみた。全てをしっかり理解していないので、効率的じゃなさそうだけど、とりあえずこれで出来た。

$(function(){
    jQuery.event.props.push('dataTransfer');

    $(document).on('drop', '.drop', function(evt){
        evt.stopPropagation();
        evt.preventDefault();

        var files = evt.dataTransfer.files;
        var url = $(this).attr('name');

        $.when(
            $.each(files, function(idx, file) {
                upload(url, idx, file);
            })
        ).done(function(){
            $('#popup').delay(2000).fadeOut('slow');
        });
    });

    $(document).on("dragenter", '.drop', false);
    $(document).on('dragover', '.drop', function(evt){
        $(this).css({'color':'#0000ff', 'width':'200px'});
        return false;
    });
    $(document).on('dragleave', '.drop', function(evt){
        $(this).css({'color' : '#000000', 'width':'130px'});
        return false;
    });
});

function upload(url, idx, file){
    var dfd = $.Deferred();
    fd = new FormData();
    fd.append('file',file);
    $.ajax({
        url: url,
        type: "POST",
        data: fd,
        processData: false,
        contentType: false,
        beforeSend:function(){
            if($('#popup').length == 0){
                $('#container').append('<div id="popup" display="none"></div>');
            }else{
                if(! $('#popup span').is(':visible')){
                    $('#popup').empty().fadeIn('first');
                }
            }
            $('#popup').append('<span class="file_' + idx  + '">' + file.name + '<br></span>');
        },
        success:function(){
            $('.file_' + idx).css({'color':'#00ccff'});
        },
        error:function(){
            $('.file_' + idx).css({'color':'#ff3333'});
        },
        complete:function(){
            $('.file_' + idx).fadeOut('slow');
            setTimeout(function(){
                dfd.resolve();
            }, 2000);
        }
    });
    return dfd.promise();
}