Drag and Dropでファイルを簡単にアップロードできるコンテンツを作れるDropzone.js

Dropzone.js

dropzonejs.com

2014月7月1日: dropzone.js のバージョンが上がり、以前の記事の内容では動作しないものが多くなっていたため、2014年7月1日時点での最新版 3.10.2 の仕様にあわせて記事内容を見直し、改訂しています。(更新が遅くなってしまってすみません。)

サポートしているブラウザは
Chrome 7+
Firefox 4+
IE 10+
Opera 12+
(Mac版のOperaではバグがあるため現在は無効のようです)
Safari 5+

となっています。

ドラッグアンドドロップが利用できないブラウザのためには、
クリックするとinput:fileで表示されるファイル選択ウィンドウを表示させたり、
動作しなかったときの処理を書いて対応することが可能となっています。

動作方法

まず実際に動かしてみましょう。
事前にdropzoneを下記よりダウンロードして、
head中などで読み込んでおきます

dropzone.js

<script type="text/javascript" src="js/dropzone.js"></script>

とりあえず表示させるのはとても簡単です。

<form action="/file-upload" class="dropzone" id="my-awesome-dropzone"></form>

上記のようなformを書いてあげます。
領域が分かりやすいようにborderとwidth、heightを指定してあります。
action属性に、ファイルのアップロード先を書いておきます。

こんな感じに出力されたかと思います。

サンプル1

ファイルをドラッグアンドドロップ、または領域をクリックすることでアップロードができます。

複数ファイルを一度にドロップすることもできます。

データはpost/に送信されてはいますが、保存はしていません
helloと一行書いてあるだけのソースですのでご安心を。

ファイルがドロップされるとデフォルトではファイル名、サイズ、プレビュー、成功したかのマーク、エラーのマークが出力されるようになっています。

何が行われているのか

領域にファイルがドロップされると何が起こっているのでしょうか。
ドロップされたデータはパラメーターの一部として、 actionで指定されたurlにXHRで投げられています。

なので、実際にはファイルを受けるサーバーサイドのプログラムを
別ファイルとして用意しておいてあげる必要があります。

form 以外の要素を使用することもできる

Dropzone.jsはフォームだけで無く、
div他の要素に対してドロップ領域を作成することもできるので、早速作成してみましょう。

id属性boxのdivを一つ追加しておきます。

<div id="stage"></div>

Dropzone で ドロップ領域を作成するには、 jQueryオブジェクトから呼び出す方法とnewしてDropzoneクラスのインスタンスを作成する方法があります。

jQuery オブジェクトを利用する場合は事前に jQuery を読み込んでおきましょう。

// jQueryオブジェクトから呼び出す方法
$("div#box").dropzone({ url: "post" });

// Dropzoneクラスのインスタンスを作成する方法 var myDropzone = new Dropzone("div#box", { url: "post/"})

とりあえず上の一行を書いてみましょう。
引数のurlにはアップロード先のURLを指定しておきます。
データを処理するためのプログラムを書いて置いておきましょう。

プレビューで表示されるサムネイルのサイズや
アップロードするファイルの上限、
自動アップロードの有無、フォールバックの処理などは引数で渡してあげるか、
インスタンスのoptionsの中身を上書きしてあげる事で対応することで、
機能を変更する事ができます。

var myDropzone = new Dropzone($("#boxs"),{
    url: "test.php", // test.phpにアップロードする
    parallelUploads: 1, // 複数ファイルを投げられた時は一つずつアップロード
    maxThumbnailFilesize: 1, // サムネイルの最大サイズを1MBにする
    maxFilesize: 0.5, // アップロードできる最大サイズを0.5MBにする
});

myDropzone.options.previewTemplate = '<div class="preview file-preview"> <div class="details"></div> <div class="filename"><span></span></div> <div class="progress"><span class="load"></span><span class="upload"></span></div> <div class="error-message"><span></span></div> <div class="color"></div></div>'; // プレビューエリアのレイアウトテンプレートの変更

といった感じです。
たくさんオプションはあるけど、
ドキュメントを見てもどのように設定したらいいかわらん!
って方は一度インスタンスを作成して、
console.logでoptionsの中身を見てみるとデフォルトの値が見れるので参考になるかもしれません。

一応ドキュメントを参考に、オプションの一覧を書きだしておきました。

オプション一覧

オプション 説明
url ファイルのアップロード先
method "post" か "put" デフォルトでは "post"
parallelUploads 同時アップロードの制限数
maxFilesize アップロードするファイルの上限サイズ(MB単位で指定する)
paramNane アップロードする際のFileのパラメーター名。
デフォルトはfiles
uploadMultiple 複数アップロードを許可するかどうか
headers サーバーに送るヘッダーをオブジェクトで指定する
Eg: headers: { "My-Awesome-Header": "header value" }
previewsContainer プレビュー画像やファイルの情報をどこに表示させるかを指定できる。
HTMLElement か CSSセレクタを指定することが出来る
clickable dropzoneが適用されている要素をクリックして、ファイルのアップロードを行うことが出来るようにするかどうか。true or falseで指定する。HTMLElement かCSSセレクタを指定して要素を指定することも出来る
createImageThumbnails サムネイルを作成するかどうか。
true or falseで指定する
maxThumbnailFilesize 生成するサムネイルの上限を指定する。
これを超える時はサムネイルは作成されない。
thumbnailWidth サムネイルの横幅を指定する(デフォルトは100px)
thumbnailHeight サムネイルの縦幅を指定する(デフォルトは100px)
init Dropzone が 初期化された時に呼ばれる関数を設定できる。
acceptedFiles 許可するファイルの mime type をカンマ区切りで指定する。
Eg.: image/*,application/pdf,.psd
もし clickable オプションを有効にしていた場合は見えない file input に accept パラメーターが設定される
accept ファイルを受け取ってからの処理を書き換える。
autoProcessQueue ドロップされてから自動でアップロードの処理を行うかどうか。
falseに指定した場合は自動アップロードされず、自分でmyDZ.processFile(file)やmyDZ.filesQueue.push(file); でファイルをキューに入れ、myDZ.processQueue();を実行する必要がある。
previewTemplate ファイルのプレビューエリアのテンプレートを書き換える。
forceFallback 強制的に Fallback の処理を有効にする
fallback ブラウザがdropzoneの動作をサポートしていない場合に呼ばれる処理を書くことが出来る。

previeTemplateのデフォルトのテンプレートは公式に掲載されています。
ファイル名の表示部分はclass="filename"、 のようにclass名と紐付いているので、
これらを削除することで表示をさせないようにすることができます。

<div class="dz-preview dz-file-preview">
  <div class="dz-details">
    <div class="dz-filename"><span data-dz-name></span></div>
    <div class="dz-size" data-dz-size></div>
    <img data-dz-thumbnail />
  </div>
  <div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
  <div class="dz-success-mark"><span>✔</span></div>
  <div class="dz-error-mark"><span>✘</span></div>
  <div class="dz-error-message"><span data-dz-errormessage></span></div>
</div>

イベントもたくさん用意されてる

dropzoneにはイベントもたくさん用意されているので、
柔軟なカスタマイズが行えるようになっています。

  • サムネイルが生成されたときに発火するthumbnail
  • エラー発生時に起こるerror
  • ファイルのドラッグが要素の上にいるときに起こるdragover
  • アップロード中に発火し、進行状態を受け取れるuploadprogress

など、他にも色々あります

on、offを使ってイベントを登録、削除します。

myDropzone.on("dragover",function(){
  console.log("ドラッグが真上にいるよ!!");
});

また、要素をドラッグ中にはdrag-overや、
clickableが有効なときにはclickableクラスが追加されるといったように、
状態が変化した際にはclassが付くようなので、
これを利用して。スタイルの変更も行うといったこともできそうです。

Demo

そんなdropzoneを使ってデモを作ってみました。
ドロップされた画像ファイルから多く使われている色を10色表示するというだけのデモです。

DEMO

一度にアップロードできるファイル数を1つに制限しています。

こちらで使われているファイル一式は Github にアップロードしていますので必要であれば以下からダウンロードしてみてください。

https://github.com/turusuke/try/tree/master/dropzone

特徴色の抽出は別のPHPにて行なっています。
送受信しているのはファイルと色のデータだけで、
ファイルの保存や記録は一切行なっていません。

dropzoneより送られたデータを元に色を解析して結果を返して、
それをユーザ側で受け取って表示しているだけのデモです。

ファイルをアップロードするだけでなく、
生成されるプレビューを利用して、画像を一気にトリミングしたい時などにも
使えるかもしれませんね!

dropzonejs.com