|
Spring-MVCの散歩道 > 応用の森(jQuery/JavaScript 編) > dropzone.jsを使用した、Ajaxでのファイルアップロードサンプル
|
$(function(){
/**
* アップロードチェック用のファイルタイプと拡張子定義
*/
FileTypes = {
image: {
description:'画像ファイル',
matcher:[/^image¥//],
extension: [/¥.jpeg$/i,/¥.jpg$/i, /¥.gif$/i, /¥.png$/i, /¥.svg$/i]
},
audio: {
description:'音声ファイル',
matcher:['audio/mp3'],
extension: [/¥.mp3$/i]
},
video: {
description:'動画ファイル',
matcher:['video/quicktime', 'video/mp4'],
extension: [/¥.mov$/i, /¥.mp4$/i]
},
excel: {
description:'エクセルファイル',
matcher:[
//'application/vnd.ms-excel',
//'application/vnd.ms-excel.sheet.macroEnabled.12',
/^application¥/vnd.ms-excel/,
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // *.xlsx
],
extension: [/¥.xls$/i, /¥.xlsx$/i, /¥.xlsm$/i]
},
csv: {
description: 'CSVファイル',
//csv形式ファイルの場合、file.type == ""(空文字) で来ることがある
//OS上のファイル⇔アプリケーション関連付けの問題
matcher: ['', ,text/csv', 'application/vnd.ms-excel'],
extension: [ /¥.csv$/i ]
},
xml: {
description: 'XMLファイル',
matcher: ['text/xml']
},
text: {
description: 'テキストファイル',
matcher: ['text/plain']
},
pdf: {
description: 'PDFファイル',
extension: [ /¥.pdf$/i ]
},
zip: {
description: 'ZIPファイル',
extension: [/¥.zip$/i ]
}
};
/**************************************************/
/**
* Dropzone オブジェクト
* opt.selector :dropzone セレクタ
* opt.upload : アップロードボタンセレクタ
* opt.maxfilesiz:アップロード可能ファイルタイプ
* opt.maxfiles :アップロード可能ファイルサイズ
* opt.filetype :添付ファイル最大数
* ※注意)underscore.js を必要とします。
*/
myDropzone = function(opt) {
var _maxsize = opt.maxfilesize;
var _maxFiles = opt.maxfiles;
var _filetype = opt.filetype;
var _upload_selector = opt.upload; //アップロードボタン
var _reason = "";
Dropzone.autoDiscover = false; //おまじない(これ指定しないと、いきなりinit定義の関数が実行された)
//Dropzoneインスタンス生成
uiDropzone = new Dropzone(opt.selector, {
//アップロード処理自体は、Dropzoneの機能ではなく
//別のAjaxなんかを使って行うのでここはダミーでよい
"url":"#",
//ファイルドロップ時ハンドラの定義
init: function() {
this.on("addedfile", checkUploadStatusHandler), //ファイル追加時
this.on("removedfile", checkUploadStatusHandler), //ファイル削除時
this.on("maxfilesexceeded", checkReachHandler) //ファイル数がmaxFilesの指定を超えてた時に呼び出される。
},
//acceptファイルを受け取ってからの処理を書き換える。
accept: checkAccept, //ファイルがドロップされたときの、ファイルタイプのチェックハンドラ
autoDiscover:false,
autoProcessQueue:false, //ドロップした時点で送信実行しない
paramName: "file", // The name that will be used to transfer the file
uploadMultiple:"false", //falseでも複数大丈夫みたい
maxFiles:_maxFiles, //1度にアップロード出来るファイルの数
maxFilesize: _maxsize, //1つのファイルの最大サイズ( MB)
addRemoveLinks: 'true',
dictDefaultMessage: '<span class="icon icon-ui-file"></span>ファイルをここにドラッグアンドドロップ<small>またはクリックで場所を指定</small>',
dictFallbackMessage: "ブラウザーがドラッグアンドドロップでのアップロードに対応していません",
dictFileTooBig: "サイズが大きすぎます({{filesize}}MB)。上限は{{maxFilesize}}MBです",
dictInvalidFileType: "この形式のファイルはアップロードできません",
dictResponseError: "エラーが発生しました。コード: {{statusCode}}",
dictCancelUpload: "アップロードをキャンセル",
dictCancelUploadConfirmation: "アップロードをキャンセルしてよろしいですか",
dictRemoveFile: "",
dictMaxFilesExceeded: "アップロード可能なファイル数の上限に達しました。",
});
/**
* ファイルタイプのチェックを行います
* file : チェックするファイル情報
*/
function checkFiletype(file){
// 1) ファイル種別チェック
//ファイルタイプのマッチングチェック
// str : checkする文字列
// matcher:checkパターン
var isMatch = function(str, matcher){
if(str.length==0) return true;
//正規表現チェック
var chk = _.isRegExp(matcher);
if(chk){
return str.match(matcher); //正規表現match
}else{
return str == matcher; //文字列match
}
return false;
};
var isOK = false;
// 1-1) コンテントタイプチェック
if (_.isArray(_filetype.matcher) && !_.isEmpty(_filetype.matcher)) {
for (var i = 0; i < _filetype.matcher.length; i++) {
var matcher = _filetype.matcher[i];
var ret = isMatch(file.type, matcher);
if (ret) {
isOK = true;
break;
}
}
if(isOK === false){
_reason = _filetype.description + 'を選択してください。';
return false;
}
}
// 1-2) ファイル拡張子チェック
if (_.isArray(_filetype.extension) && !_.isEmpty(_filetype.extension)) {
isOK = false;
for (var i = 0; i < _filetype.extension.length; i++) {
var ext = _filetype.extension[i];
var ret = isMatch(file.name, ext);
if (ret) {
isOK = true;
break;
}
}
if(isOK === false){
_reason = _filetype.description + 'を選択してください。';
return false;
}
}
if(isOK) {
// 2) ファイルサイズチェック
// サイズチェック(通常はcheckAcceptじゃなく、Dropzoneのデフォルトチェックが先に判定される)
if(_maxsize > 0 && file.size > (_maxsize*1024*1024)){
// メッセージは Dropzone.options.fileupload.dictFileTooBig が表示される。
return false; //Check NG
}else if(file.size <= 0){
_reason = '空ファイルです。';
return false; //Check NG
}
return true; //Check OK
}
}
/**
* Dropzoneドロップファイルタイプのチェックハンドラ
* file : ドロップされたファイル情報
* done : 処理結果表示
*/
function checkAccept(file, done){
if (_filetype) {
//ファイルタイプをチェックする
var isOK = checkFiletype(file);
if(isOK){ //添付ファイル正常時
//自分の親セレクタを見つけて、その子セレクタの吹き出し領域を非表示
$(file.previewElement).find('.dz-error-message').hide();
$(file.previewElement).find('.dz-progress').hide(); //progress barも隠蔽
done();
}else{ //添付ファイル異常時
done(_reason); //NGならメッセージを表示
}
}
}
/**
* Dropzoneドロップファイル状態チェックイベントハンドラ
* UI コントロール
* ファイルタイプ・ファイルサイズ・ファイル添付数の状態をチェックして
* 「アップロード」ボタンの表示/非表示を設定する
*/
function checkUploadStatusHandler(){
if(_upload_selector) { //「アップロード」ボタンセレクタ指定あり
var isOK = true;
if (uiDropzone.files.length==0 || uiDropzone.files.length > _maxFiles) {
//添付ファイルがあり、最大添付数を超えたら「アップロード」ボタンを非表示
isOK = false;
} else {
isOK = true;
for(i=0 ; i < uiDropzone.files.length ; i++) {
//添付されたファイルタイプ・サイズをチェックする
isOK = checkFiletype(uiDropzone.files[i]);
if(!isOK) break; //1個でもNGなら break
}
}
if(isOK) {
$(_upload_selector).show(); //アップロードボタン表示
} else {
$(_upload_selector).hide(); //アップロードボタン非表示
}
}
}
/**
* 最大ファイル添付数に達した時に呼び出されるイベントハンドラ
*/
function checkReachHandler(file) {
$(_upload_selector).hide(); //アップロードボタン非表示
}
return uiDropzone; //Dropzoneインスタンスを返す
}
});
|