ドラッグアンドドロップで複数ファイルをアップロード【jQuery/Laravel】


いまさらながら複数ファイルアップロードするやり方を忘れないようにメモ

実現イメージ

赤いところにファイルをドロップするとファイルが追加されて、送信を押すとまとめてアップロードする最低限のサンプル

HTML

upload.blade.php
    <div id="upload_files_area" style="background-color:red; height:300px; width:100%;"></div>
    <button id="send">送信</button>

JavaScript

upload.js
    $(function(){
        //FormDataオブジェクトを作成
        var formData = new FormData();

        //ファイルがドロップされたときに呼ばれる
        $('#upload_files_area').on('drop', function(ev) {
            var files = ev.originalEvent.dataTransfer.files;
            for (var i = 0; i < files.length; i++) {
                //FormDataオブジェクトにファイルを追加
                //名前は'document_files[]'ってしてやる
                formData.append('document_files[]', files[i]);
            }
        });

        //送信
        $('#send').click(function(){
            $.ajax({
                url:'/upload_exec',
                type:'post',
                data: formData,
                processData: false,
                contentType: false,
                cache: false,
            });
        });
    });

PHP

UploadController
    public function uploadExec(Request $request)
    {
        $files = $request->file('document_files');
        foreach ($files as $file) {
            //ここではS3にアップロード
            Storage::disk('s3')->putFile('path', $file);
        }
    }

まとめ

これだけだとファイルをドロップしても画面上になにも表示されないので、実際にはFormDataに追加されているファイルを表示したり、削除するような機能を追加する必要があると思う。FormDataに追加されているファイルはformData.getAll('document_files[]');で配列として取得できるので、それを適当に操作してやると良い。