/**
* fileUploadArea 0.1
*
* Copyright (c) 2009 Peter Rudolfsen
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Date: 2009-11-27
*/
/**
* Add 'sum_numbers' to Array.prototype if it doesn't exist
* Not called 'sum' to avoid possible crashes with other implementations of 'sum'
*/
Array.prototype.sum_numbers = function () {
return (!this.length) ? 0 : this.slice(1).sum_numbers() + ((typeof this[0] == 'number') ? this[0] : 0);
};
(function ($) {
/**
* Private variables
*/
var options = {},
totalSize = 0,
numFiles = 0,
loadQueue = [],
completeQueue = [];
/**
* Private functions
*/
function dragEnter(e) {
options.onDragEnter.call(this);
e.stopPropagation();
e.preventDefault();
}
function dragOver(e) {
options.onDragOver.call(this);
e.stopPropagation();
e.preventDefault();
}
function dragLeave(e) {
options.onDragLeave.call(this);
e.stopPropagation();
e.preventDefault();
}
function drop(e) {
var files = e.dataTransfer.files,
i = 0;
numFiles = files.length;
e.stopPropagation();
e.preventDefault();
/**
* Call the onDrop callback
* Calculate total file size
*/
for (i = 0; i < numFiles; i++) {
options.onDrop.call(this, files.item(i));
totalSize += files.item(i).fileSize;
}
/**
* Upload each file
*/
for (i = 0; i < numFiles; i++) {
uploadFile(files.item(i), i);
}
}
function uploadFile(file, queueId) {
var xhr = new XMLHttpRequest(),
queryString = '?',
j = 0;
xhr.upload.addEventListener('progress', function (e) {
if (e.lengthComputable) {
loadQueue[queueId] = e.loaded;
options.progress.call(file, Math.round((e.loaded * 100) / e.total), Math.round((loadQueue.sum_numbers() / totalSize) * 100));
}
}, false);
xhr.upload.addEventListener('load', function (e) {
loadQueue[queueId] = e.total;
options.progress.call(file, 100, Math.round((loadQueue.sum_numbers() / totalSize) * 100));
/**
* Not in use!
* Using the AJAX-request to complete the file, to allow for response in the complete callback
*/
}, false);
/**
* Sending name and type as GET params in the AJAX-request
*/
options.params.name = file.fileName;
options.params.type = file.type;
/**
* Build the query string based on options.params
*/
for (j in options.params) {
if (options.params.hasOwnProperty(j)) {
queryString += (j + '=' + options.params[j] + '&');
}
}
/**
* Remove trailing '&'
*/
queryString = queryString.substring(0, queryString.length - 1);
/**
* Post the file
*/
xhr.open("POST", options.url + queryString, true);
xhr.overrideMimeType('text/plain; charset=x-user-defined-binary');
xhr.onreadystatechange = function (event) {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
/**
* The upload is complete
*/
completeQueue[queueId] = 1;
options.fileComplete.call(file, xhr.responseText);
if (completeQueue.sum_numbers() === numFiles) {
options.complete.call(null);
}
} else {
throw 'Failed uploading file ' + file.fileName;
}
}
};
xhr.sendAsBinary(file.getAsBinary());
}
/**
* Plugin definition
*/
$.fn.fileUploadArea = function (opts) {
return this.each(function () {
if (typeof opts !== 'object') {
opts = {};
}
options = $.extend({}, {
url: 'upload.php',
onDragEnter: function () {},
onDragOver: function () {},
onDragLeave: function () {},
onDrop: function (file) {},
progress: function (percent, totalPercent) {},
fileComplete: function () {},
complete: function () {},
params: {}
}, opts);
this.addEventListener('dragenter', dragEnter, false);
this.addEventListener('dragover', dragOver, false);
this.addEventListener('dragleave', dragLeave, false);
this.addEventListener('drop', drop, false);
});
};
})(jQuery);