Created
July 27, 2017 00:26
-
-
Save gficher/27a77b5040cf32d7ab92c9ccfcd5d5aa to your computer and use it in GitHub Desktop.
Custom version of dmuploader.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* dmuploader.js - Jquery File Uploader - 0.1 | |
* http://www.daniel.com.uy/projects/jquery-file-uploader/ | |
* | |
* Copyright (c) 2013-2014 Daniel Morales | |
* Dual licensed under the MIT and GPL licenses. | |
* http://www.daniel.com.uy/doc/license/ | |
* | |
* This is a custom version of the original project | |
* made by Gustavo Ficher (aka gficher) | |
* http://gficher.com | |
* | |
*/ | |
(function($) { | |
var pluginName = 'dmUploader'; | |
var FileStatus = { | |
PENDING: 0, | |
UPLOADING: 1, | |
COMPLETED: 2, | |
FAILED: 3, | |
CANCELLED: 4 //(by the user) | |
}; | |
// These are the plugin defaults values | |
var defaults = { | |
url: document.URL, | |
method: 'POST', | |
extraData: {}, | |
headers: {}, | |
maxFileSize: 0, | |
allowedTypes: '*', | |
extFilter: null, | |
dataType: null, | |
fileName: 'file', | |
auto: true, | |
skipChecks: false, | |
onInit: function(){}, | |
onFallbackMode: function() {}, | |
onNewFile: function(){}, | |
onBeforeUpload: function(){}, | |
onComplete: function(){}, | |
onUploadProgress: function(){}, | |
onUploadSuccess: function(){}, | |
onUploadError: function(){}, | |
onUploadCancel: function(){}, | |
onFileTypeError: function(){}, | |
onFileSizeError: function(){}, | |
onFileExtError: function(){}, | |
}; | |
var DmUploader = function(element, options) | |
{ | |
this.element = $(element); | |
this.settings = $.extend({}, defaults, options); | |
if(!this.settings.skipChecks && !this.checkBrowser()){ | |
return false; | |
} | |
this.init(); | |
return true; | |
}; | |
var DmUploaderFile = function(file) | |
{ | |
this.file = file; | |
this.jqXHR = null; | |
this.status = FileStatus.PENDING; | |
this.id = -1; | |
}; | |
DmUploaderFile.prototype.setId = function(id) | |
{ | |
this.id = id; | |
}; | |
DmUploaderFile.prototype.cancel = function() | |
{ | |
switch (this.status){ | |
case FileStatus.PENDING: | |
this.status = FileStatus.CANCELLED; | |
break; | |
case FileStatus.UPLOADING: | |
this.status = FileStatus.CANCELLED; | |
this.jqXHR.abort(); | |
break; | |
default: | |
return false; | |
} | |
return true; | |
}; | |
DmUploaderFile.prototype.upload = function(widget, single) | |
{ | |
var file = this; | |
// Cancelled by the user? | |
if (!single && (file.status == FileStatus.CANCELLED)){ | |
widget.processQueue(); | |
return false; | |
} | |
// Uploading, or completed files... | |
if (file.status == FileStatus.UPLOADING || | |
file.status == FileStatus.COMPLETED){ | |
if (!single){ | |
widget.processQueue(); | |
} | |
return false; | |
} | |
// Form Data | |
var fd = new FormData(); | |
fd.append(widget.settings.fileName, file.file); | |
// Append extra Form Data | |
$.each(widget.settings.extraData, function(exKey, exVal){ | |
if (typeof exVal == 'function') { exVal = exVal(); } | |
fd.append(exKey, exVal); | |
}); | |
widget.settings.onBeforeUpload.call(widget.element, file.id); | |
if (!single){ | |
widget.queueRunning = true; | |
} | |
file.status = FileStatus.UPLOADING; | |
// Ajax Submit | |
file.jqXHR = $.ajax({ | |
url: widget.settings.url, | |
type: widget.settings.method, | |
dataType: widget.settings.dataType, | |
data: fd, | |
headers: widget.settings.headers, | |
cache: false, | |
contentType: false, | |
processData: false, | |
forceSync: false, | |
xhr: function(){ | |
var xhrobj = $.ajaxSettings.xhr(); | |
if(xhrobj.upload){ | |
xhrobj.upload.addEventListener('progress', function(event) { | |
var percent = 0; | |
var position = event.loaded || event.position; | |
var total = event.total || event.totalSize; | |
if(event.lengthComputable){ | |
percent = Math.ceil(position / total * 100); | |
} | |
widget.settings.onUploadProgress.call(widget.element, file.id, percent); | |
}, false); | |
} | |
return xhrobj; | |
}, | |
success: function (data){ | |
file.status = FileStatus.COMPLETED; | |
widget.settings.onUploadSuccess.call(widget.element, file.id, data); | |
}, | |
error: function (xhr, status, errMsg){ | |
// If the status is: cancelled (by the user) don't invoke the error callback | |
if (file.status != FileStatus.CANCELLED) { | |
file.status = FileStatus.FAILED; | |
widget.settings.onUploadError.call(widget.element, file.id, errMsg); | |
} else { | |
//widget.settings.onUploadCancel.call(widget.element, file.id, errMsg); | |
} | |
}, | |
complete: function(){ | |
if (widget.settings.auto){ | |
widget.processQueue(); | |
} | |
} | |
}); | |
return true; | |
}; | |
// Public API methods | |
DmUploader.prototype.methods = { | |
cancel: function(id) { | |
/* Stops(if uploading) and Remove the upload from Queue */ | |
if (id > (this.queue.length - 1)){ | |
return false; | |
} | |
var widget = DmUploader.prototype.widget; | |
widget.settings.onUploadCancel.call(widget.element, id); | |
return this.queue[id].cancel(); | |
}, | |
cancelAll: function() { | |
/* Same as cancel, but for all pending uploads */ | |
var nCancels = 0; | |
var widget = DmUploader.prototype.widget; | |
$.each(this.queue, function(id, file){ | |
if (file.cancel()){ | |
nCancels++; | |
widget.settings.onUploadCancel.call(widget.element, id); | |
} | |
}); | |
return nCancels; | |
}, | |
start: function(id) { | |
/* Start or re-try the upload */ | |
if (id > (this.queue.length - 1)){ | |
return false; | |
} | |
// If we are using a File queue only allow to start (or retry) | |
// files that that were cancelled or failed (NOT files that are 'next' in | |
// our queue. | |
if (this.settings.auto && (id >= this.queuePos)){ | |
return false; | |
} | |
return this.queue[id].upload(this, true); | |
}, | |
supportsProgress: function() { | |
var xhrobj = $.ajaxSettings.xhr(); | |
return (xhrobj.upload !== undefined); | |
}, | |
supportsDND: function() { | |
return (this.checkEvent('drop', this.element) && !this.checkEvent('dragstart', this.element)); | |
} | |
}; | |
DmUploader.prototype.checkBrowser = function() | |
{ | |
if(window.FormData === undefined){ | |
this.settings.onFallbackMode.call(this.element, 'Browser doesn\'t support Form API'); | |
return false; | |
} | |
if(this.element.find('input[type=file]').length > 0){ | |
return true; | |
} | |
if (!this.checkEvent('drop', this.element) || !this.checkEvent('dragstart', this.element)){ | |
this.settings.onFallbackMode.call(this.element, 'Browser doesn\'t support Ajax Drag and Drop'); | |
return false; | |
} | |
return true; | |
}; | |
DmUploader.prototype.checkEvent = function(eventName, element) | |
{ | |
element = element || document.createElement('div'); | |
eventName = 'on' + eventName; | |
var isSupported = eventName in element; | |
if(!isSupported){ | |
if(!element.setAttribute){ | |
element = document.createElement('div'); | |
} | |
if(element.setAttribute && element.removeAttribute){ | |
element.setAttribute(eventName, ''); | |
isSupported = typeof element[eventName] == 'function'; | |
if(typeof element[eventName] != 'undefined'){ | |
element[eventName] = undefined; | |
} | |
element.removeAttribute(eventName); | |
} | |
} | |
element = null; | |
return isSupported; | |
}; | |
DmUploader.prototype.init = function() | |
{ | |
var widget = this; | |
DmUploader.prototype.widget = widget; | |
widget.queue = []; | |
widget.queuePos = -1; | |
widget.queueRunning = false; | |
// -- Drag and drop event | |
widget.element.on('drop', function (evt){ | |
evt.preventDefault(); | |
var files = evt.originalEvent.dataTransfer.files; | |
widget.queueFiles(files); | |
}); | |
//-- Optional File input to make a clickable area | |
widget.element.find('input[type=file]').on('change', function(evt){ | |
var files = evt.target.files; | |
widget.queueFiles(files); | |
$(this).val(''); | |
}); | |
this.settings.onInit.call(this.element); | |
}; | |
DmUploader.prototype.queueFiles = function(files) | |
{ | |
var j = this.queue.length; | |
for (var i= 0; i < files.length; i++) | |
{ | |
var file = files[i]; | |
// Check file size | |
if((this.settings.maxFileSize > 0) && | |
(file.size > this.settings.maxFileSize)){ | |
this.settings.onFileSizeError.call(this.element, file); | |
continue; | |
} | |
// Check file type | |
if((this.settings.allowedTypes != '*') && | |
!file.type.match(this.settings.allowedTypes)){ | |
this.settings.onFileTypeError.call(this.element, file); | |
continue; | |
} | |
// Check file extension | |
if(this.settings.extFilter !== null){ | |
var extList = this.settings.extFilter.toLowerCase().split(';'); | |
var ext = file.name.toLowerCase().split('.').pop(); | |
if($.inArray(ext, extList) < 0){ | |
this.settings.onFileExtError.call(this.element, file); | |
continue; | |
} | |
} | |
var fileObj = new DmUploaderFile(file); | |
this.queue.push(fileObj); | |
var index = this.queue.length - 1; | |
fileObj.setId(index); | |
this.settings.onNewFile.call(this.element, index, file); | |
} | |
// Only start Queue if we haven't! | |
if(this.queueRunning){ | |
return false; | |
} | |
// and only if new Files were succefully added | |
if(this.queue.length == j){ | |
return false; | |
} | |
if (this.settings.auto){ | |
this.processQueue(); | |
} | |
return true; | |
}; | |
DmUploader.prototype.processQueue = function() | |
{ | |
this.queuePos++; | |
if(this.queuePos >= this.queue.length){ | |
this.settings.onComplete.call(this.element); | |
// Wait until new files are droped | |
this.queuePos = (this.queue.length - 1); | |
this.queueRunning = false; | |
return; | |
} | |
this.queue[this.queuePos].upload(this, false); | |
}; | |
$.fn.dmUploader = function(args){ | |
// Now we are only able to initialize only one widget at the time | |
if($(this).length != 1){ | |
$.error('Need one element to initialize jQuery.dmUploader'); | |
return false; | |
} | |
var plugin = $(this).data(pluginName); | |
if(!plugin){ | |
$(this).data(pluginName, new DmUploader(this, args)); | |
} else if (plugin.methods[args]){ | |
return plugin.methods[args].apply(plugin, Array.prototype.slice.call(arguments, 1)); | |
} else { | |
$.error('Method ' + args + ' does not exist on jQuery.dmUploader'); | |
return false; | |
} | |
return true; | |
}; | |
// -- Disable Document D&D events to prevent opening the file on browser when we drop them | |
$(document).on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); }); | |
$(document).on('dragover', function (e) { e.stopPropagation(); e.preventDefault(); }); | |
$(document).on('drop', function (e) { e.stopPropagation(); e.preventDefault(); }); | |
})(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment