/*!
* jQuery Upload File Plugin
* version: 3.1.8
* @requires jQuery v1.5 or later & form plugin
* Copyright (c) 2013 Ravishanker Kusuma
* http://hayageek.com/
*/
(function ($) {
if($.fn.ajaxForm == undefined) {
$.getScript("/js/jquery.form.js");
}
var feature = {};
feature.fileapi = $("").get(0).files !== undefined;
feature.formdata = window.FormData !== undefined;
$.fn.uploadFile = function (options) {
// This is the easiest way to have default options.
var s = $.extend({
// These are the defaults.
url: "",
method: "POST",
enctype: "multipart/form-data",
formData: null,
returnType: null,
allowedTypes: "*",
acceptFiles: "*",
fileName: "file",
formData: {},
dynamicFormData: function () {
return {};
},
maxFileSize: -1,
maxFileCount: -1,
multiple: true,
dragDrop: true,
autoSubmit: true,
showCancel: true,
showAbort: true,
showDone: true,
showDelete: true,
showError: true,
showStatusAfterSuccess: true,
showStatusAfterError: true,
showFileCounter: true,
fileCounterStyle: "). ",
showProgress: true,
nestedForms: true,
showDownload: false,
onLoad: function (obj) {},
onSelect: function (files) {
return true;
},
onSubmit: function (files, xhr) {},
onSuccess: function (files, response, xhr, pd) {},
onError: function (files, status, message, pd) {},
onCancel: function (files, pd) {},
downloadCallback: false,
deleteCallback: false,
afterUploadAll: false,
uploadButtonClass: "btn btn-success",
dragDropStr: " Arrastre y suelte sus archivos aqui",
abortStr: "Detener",
cancelStr: "Cancelar",
deletelStr: "Borrar",
doneStr: "Eliminar",
multiDragErrorStr: "Arrastrar y soltar no está permitido",
extErrorStr: "no es una extensión permitida. Extensiones permitidas: ",
sizeErrorStr: "excede el tamaño máximo por archivo. Tamaño máximo: ",
uploadErrorStr: "La subida esta inhabilitada",
maxFileCountErrorStr: " supera la cantidad máxima de archivos permitida. Limite:",
downloadStr: "Descargar",
customErrorKeyStr: "jquery-upload-file-error",
showQueueDiv: false,
statusBarWidth: '80%',
dragdropWidth: "100%",
showPreview: false,
previewHeight: "auto",
previewWidth: "100%"
}, options);
this.fileCounter = 1;
this.selectedFiles = 0;
this.fCounter = 0; //failed uploads
this.sCounter = 0; //success uploads
this.tCounter = 0; //total uploads
var formGroup = "ajax-file-upload-" + (new Date().getTime());
this.formGroup = formGroup;
this.hide();
this.errorLog = $("
"); //Writing errors
this.after(this.errorLog);
this.responses = [];
if(!feature.formdata) //check drag drop enabled.
{
s.dragDrop = false;
}
if(!feature.formdata) {
s.multiple = false;
}
var obj = this;
var uploadLabel = $(' ' + $(this).html() + '
');
$(uploadLabel).addClass(s.uploadButtonClass);
//wait form ajax Form plugin and initialize
(function checkAjaxFormLoaded() {
if($.fn.ajaxForm) {
if(s.dragDrop) {
var dragDrop = $('').width(s.dragdropWidth);
$(obj).before(dragDrop);
$(dragDrop).append(uploadLabel);
$(dragDrop).append($(s.dragDropStr));
setDragDropHandlers(obj, s, dragDrop);
} else {
$(obj).before(uploadLabel);
}
s.onLoad.call(this, obj);
createCutomInputFile(obj, formGroup, s, uploadLabel);
} else window.setTimeout(checkAjaxFormLoaded, 10);
})();
this.startUpload = function () {
$("." + this.formGroup).each(function (i, items) {
if($(this).is('form')) $(this).submit();
});
}
this.getFileCount = function () {
return obj.selectedFiles;
}
this.stopUpload = function () {
$(".ajax-file-upload-abort").each(function (i, items) {
if($(this).hasClass(obj.formGroup)) $(this).click();
});
}
this.cancelAll = function () {
$(".ajax-file-upload-cancel").each(function (i, items) {
if($(this).hasClass(obj.formGroup)) $(this).click();
});
}
this.update = function (settings) {
//update new settings
s = $.extend(s, settings);
}
//This is for showing Old files to user.
this.createProgress = function (filename) {
var pd = new createProgressDiv(this, s);
pd.progressDiv.show();
pd.progressbar.width('100%');
pd.filename.html(obj.fileCounter + s.fileCounterStyle + filename);
obj.fileCounter++;
obj.selectedFiles++;
if(s.showDownload) {
pd.download.show();
pd.download.click(function () {
if(s.downloadCallback) s.downloadCallback.call(obj, [filename]);
});
}
pd.del.show();
pd.del.click(function () {
pd.statusbar.hide().remove();
var arr = [filename];
if(s.deleteCallback) s.deleteCallback.call(this, arr, pd);
obj.selectedFiles -= 1;
updateFileCounter(s, obj);
});
}
this.getResponses = function () {
return this.responses;
}
var checking = false;
function checkPendingUploads() {
if(s.afterUploadAll && !checking) {
checking = true;
(function checkPending() {
if(obj.sCounter != 0 && (obj.sCounter + obj.fCounter == obj.tCounter)) {
s.afterUploadAll(obj);
checking = false;
} else window.setTimeout(checkPending, 100);
})();
}
}
function setDragDropHandlers(obj, s, ddObj) {
ddObj.on('dragenter', function (e) {
e.stopPropagation();
e.preventDefault();
});
ddObj.on('dragover', function (e) {
e.stopPropagation();
e.preventDefault();
});
ddObj.on('drop', function (e) {
e.preventDefault();
obj.errorLog.html("");
var files = e.originalEvent.dataTransfer.files;
if(!s.multiple && files.length > 1) {
if(s.showError) $("" + s.multiDragErrorStr + "
").appendTo(obj.errorLog);
return;
}
if(s.onSelect(files) == false) return;
serializeAndUploadFiles(s, obj, files);
});
$(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();
});
}
function getSizeStr(size) {
var sizeStr = "";
var sizeKB = size / 1024;
if(parseInt(sizeKB) > 1024) {
var sizeMB = sizeKB / 1024;
sizeStr = sizeMB.toFixed(2) + " MB";
} else {
sizeStr = sizeKB.toFixed(2) + " KB";
}
return sizeStr;
}
function serializeData(extraData) {
var serialized = [];
if(jQuery.type(extraData) == "string") {
serialized = extraData.split('&');
} else {
serialized = $.param(extraData).split('&');
}
var len = serialized.length;
var result = [];
var i, part;
for(i = 0; i < len; i++) {
serialized[i] = serialized[i].replace(/\+/g, ' ');
part = serialized[i].split('=');
result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
}
return result;
}
function serializeAndUploadFiles(s, obj, files) {
for(var i = 0; i < files.length; i++) {
if(!isFileTypeAllowed(obj, s, files[i].name)) {
if(s.showError) $("" + files[i].name + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(obj.errorLog);
continue;
}
if(s.maxFileSize != -1 && files[i].size > s.maxFileSize) {
if(s.showError) $("" + files[i].name + " " + s.sizeErrorStr + getSizeStr(s.maxFileSize) + "
").appendTo(
obj.errorLog);
continue;
}
if(s.maxFileCount != -1 && obj.selectedFiles >= s.maxFileCount) {
if(s.showError) $("" + files[i].name + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo(
obj.errorLog);
continue;
}
obj.selectedFiles++;
var ts = s;
var fd = new FormData();
var fileName = s.fileName.replace("[]", "");
fd.append(fileName, files[i]);
var extraData = s.formData;
if(extraData) {
var sData = serializeData(extraData);
for(var j = 0; j < sData.length; j++) {
if(sData[j]) {
fd.append(sData[j][0], sData[j][1]);
}
}
}
ts.fileData = fd;
var pd = new createProgressDiv(obj, s);
var fileNameStr = "";
if(s.showFileCounter) fileNameStr = obj.fileCounter + s.fileCounterStyle + files[i].name
else fileNameStr = files[i].name;
pd.filename.html(fileNameStr);
var form = $("");
form.appendTo('body');
var fileArray = [];
fileArray.push(files[i].name);
ajaxFormSubmit(form, ts, pd, fileArray, obj, files[i]);
obj.fileCounter++;
}
}
function isFileTypeAllowed(obj, s, fileName) {
var fileExtensions = s.allowedTypes.toLowerCase().split(",");
var ext = fileName.split('.').pop().toLowerCase();
if(s.allowedTypes != "*" && jQuery.inArray(ext, fileExtensions) < 0) {
return false;
}
return true;
}
function getSrcToPreview(file, obj) {
if(file) {
obj.show();
var reader = new FileReader();
reader.onload = function (e) {
obj.attr('src', e.target.result);
};
reader.readAsDataURL(file);
}
}
function updateFileCounter(s, obj) {
if(s.showFileCounter) {
var count = $(".ajax-file-upload-filename").length;
obj.fileCounter = count + 1;
$(".ajax-file-upload-filename").each(function (i, items) {
var arr = $(this).html().split(s.fileCounterStyle);
var fileNum = parseInt(arr[0]) - 1; //decrement;
var name = count + s.fileCounterStyle + arr[1];
$(this).html(name);
count--;
});
}
}
function createCutomInputFile(obj, group, s, uploadLabel) {
var fileUploadId = "ajax-upload-id-" + (new Date().getTime());
var form = $("");
var fileInputStr = "";
if(s.multiple) {
if(s.fileName.indexOf("[]") != s.fileName.length - 2) // if it does not endwith
{
s.fileName += "[]";
}
fileInputStr = "";
}
var fileInput = $(fileInputStr).appendTo(form);
fileInput.change(function () {
obj.errorLog.html("");
var fileExtensions = s.allowedTypes.toLowerCase().split(",");
var fileArray = [];
if(this.files) //support reading files
{
for(i = 0; i < this.files.length; i++) {
fileArray.push(this.files[i].name);
}
if(s.onSelect(this.files) == false) return;
} else {
var filenameStr = $(this).val();
var flist = [];
fileArray.push(filenameStr);
if(!isFileTypeAllowed(obj, s, filenameStr)) {
if(s.showError) $("" + filenameStr + " " + s.extErrorStr + s.allowedTypes + "
").appendTo(
obj.errorLog);
return;
}
//fallback for browser without FileAPI
flist.push({
name: filenameStr,
size: 'NA'
});
if(s.onSelect(flist) == false) return;
}
updateFileCounter(s, obj);
uploadLabel.unbind("click");
form.hide();
createCutomInputFile(obj, group, s, uploadLabel);
form.addClass(group);
if(feature.fileapi && feature.formdata) //use HTML5 support and split file submission
{
form.removeClass(group); //Stop Submitting when.
var files = this.files;
serializeAndUploadFiles(s, obj, files);
} else {
var fileList = "";
for(var i = 0; i < fileArray.length; i++) {
if(s.showFileCounter) fileList += obj.fileCounter + s.fileCounterStyle + fileArray[i] + "
";
else fileList += fileArray[i] + "
";;
obj.fileCounter++;
}
if(s.maxFileCount != -1 && (obj.selectedFiles + fileArray.length) > s.maxFileCount) {
if(s.showError) $("" + fileList + " " + s.maxFileCountErrorStr + s.maxFileCount + "
").appendTo(
obj.errorLog);
return;
}
obj.selectedFiles += fileArray.length;
var pd = new createProgressDiv(obj, s);
pd.filename.html(fileList);
ajaxFormSubmit(form, s, pd, fileArray, obj, null);
}
});
if(s.nestedForms) {
form.css({
'margin': 0,
'padding': 0
});
uploadLabel.css({
position: 'relative',
overflow: 'hidden',
cursor: 'default'
});
fileInput.css({
position: 'absolute',
'cursor': 'pointer',
'top': '0px',
'width': '100%',
'height': '100%',
'left': '0px',
'z-index': '100',
'opacity': '0.0',
'filter': 'alpha(opacity=0)',
'-ms-filter': "alpha(opacity=0)",
'-khtml-opacity': '0.0',
'-moz-opacity': '0.0'
});
form.appendTo(uploadLabel);
} else {
form.appendTo($('body'));
form.css({
margin: 0,
padding: 0,
display: 'block',
position: 'absolute',
left: '-999px'
});
if(navigator.appVersion.indexOf("MSIE ") != -1) //IE Browser
{
uploadLabel.attr('for', fileUploadId);
} else {
uploadLabel.click(function () {
fileInput.click();
});
}
}
}
function createProgressDiv(obj, s) {
this.statusbar = $("").width(s.statusBarWidth);
this.preview = $("").width(s.previewWidth).height(s.previewHeight).appendTo(this.statusbar).hide();
this.filename = $("").appendTo(this.statusbar);
this.progressDiv = $("").appendTo(this.statusbar).hide();
this.progressbar = $("
").appendTo(this.progressDiv);
this.abort = $("
" + s.abortStr + "
").appendTo(this.statusbar)
.hide();
this.cancel = $("
" + s.cancelStr + "
").appendTo(this.statusbar)
.hide();
this.done = $("
" + s.doneStr + "
").appendTo(this.statusbar).hide();
this.download = $("
" + s.downloadStr + "
").appendTo(this.statusbar).hide();
this.del = $("
" + s.deletelStr + "
").appendTo(this.statusbar).hide();
if(s.showQueueDiv)
$("#" + s.showQueueDiv).append(this.statusbar);
else
obj.errorLog.after(this.statusbar);
return this;
}
function ajaxFormSubmit(form, s, pd, fileArray, obj, file) {
var currentXHR = null;
var options = {
cache: false,
contentType: false,
processData: false,
forceSync: false,
type: s.method,
data: s.formData,
formData: s.fileData,
dataType: s.returnType,
beforeSubmit: function (formData, $form, options) {
if(s.onSubmit.call(this, fileArray) != false) {
var dynData = s.dynamicFormData();
if(dynData) {
var sData = serializeData(dynData);
if(sData) {
for(var j = 0; j < sData.length; j++) {
if(sData[j]) {
if(s.fileData != undefined) options.formData.append(sData[j][0], sData[j][1]);
else options.data[sData[j][0]] = sData[j][1];
}
}
}
}
obj.tCounter += fileArray.length;
//window.setTimeout(checkPendingUploads, 1000); //not so critical
checkPendingUploads();
return true;
}
pd.statusbar.append("
" + s.uploadErrorStr + "
");
pd.cancel.show()
form.remove();
pd.cancel.click(function () {
pd.statusbar.remove();
s.onCancel.call(obj, fileArray, pd);
obj.selectedFiles -= fileArray.length; //reduce selected File count
updateFileCounter(s, obj);
});
return false;
},
beforeSend: function (xhr, o) {
pd.progressDiv.show();
pd.cancel.hide();
pd.done.hide();
if(s.showAbort) {
pd.abort.show();
pd.abort.click(function () {
xhr.abort();
obj.selectedFiles -= fileArray.length; //reduce selected File count
});
}
if(!feature.formdata) //For iframe based push
{
pd.progressbar.width('5%');
} else pd.progressbar.width('1%'); //Fix for small files
},
uploadProgress: function (event, position, total, percentComplete) {
//Fix for smaller file uploads in MAC
if(percentComplete > 98) percentComplete = 98;
var percentVal = percentComplete + '%';
if(percentComplete > 1) pd.progressbar.width(percentVal)
if(s.showProgress) {
pd.progressbar.html(percentVal);
pd.progressbar.css('text-align', 'center');
}
},
success: function (data, message, xhr) {
//For custom errors.
if(s.returnType == "json" && $.type(data) == "object" && data.hasOwnProperty(s.customErrorKeyStr)) {
pd.abort.hide();
var msg = data[s.customErrorKeyStr];
s.onError.call(this, fileArray, 200, msg, pd);
if(s.showStatusAfterError) {
pd.progressDiv.hide();
pd.statusbar.append("
ERROR: " + msg + "");
} else {
pd.statusbar.hide();
pd.statusbar.remove();
}
obj.selectedFiles -= fileArray.length; //reduce selected File count
form.remove();
obj.fCounter += fileArray.length;
return;
}
obj.responses.push(data);
pd.progressbar.width('100%')
if(s.showProgress) {
pd.progressbar.html('100%');
pd.progressbar.css('text-align', 'center');
}
pd.abort.hide();
s.onSuccess.call(this, fileArray, data, xhr, pd);
if(s.showStatusAfterSuccess) {
if(s.showDone) {
pd.done.show();
pd.done.click(function () {
pd.statusbar.hide("slow");
pd.statusbar.remove();
});
} else {
pd.done.hide();
}
if(s.showDelete) {
pd.del.show();
pd.del.click(function () {
pd.statusbar.hide().remove();
if(s.deleteCallback) s.deleteCallback.call(this, data, pd);
obj.selectedFiles -= fileArray.length; //reduce selected File count
updateFileCounter(s, obj);
});
} else {
pd.del.hide();
}
} else {
pd.statusbar.hide("slow");
pd.statusbar.remove();
}
if(s.showDownload) {
pd.download.show();
pd.download.click(function () {
if(s.downloadCallback) s.downloadCallback(data);
});
}
form.remove();
obj.sCounter += fileArray.length;
},
error: function (xhr, status, errMsg) {
pd.abort.hide();
if(xhr.statusText == "abort") //we aborted it
{
pd.statusbar.hide("slow").remove();
updateFileCounter(s, obj);
} else {
s.onError.call(this, fileArray, status, errMsg, pd);
if(s.showStatusAfterError) {
pd.progressDiv.hide();
pd.statusbar.append("
ERROR: " + errMsg + "");
} else {
pd.statusbar.hide();
pd.statusbar.remove();
}
obj.selectedFiles -= fileArray.length; //reduce selected File count
}
form.remove();
obj.fCounter += fileArray.length;
}
};
if(s.showPreview && file != null) {
if(file.type.toLowerCase().split("/").shift() == "image") getSrcToPreview(file, pd.preview);
}
if(s.autoSubmit) {
form.ajaxSubmit(options);
} else {
if(s.showCancel) {
pd.cancel.show();
pd.cancel.click(function () {
form.remove();
pd.statusbar.remove();
s.onCancel.call(obj, fileArray, pd);
obj.selectedFiles -= fileArray.length; //reduce selected File count
updateFileCounter(s, obj);
});
}
form.ajaxForm(options);
}
}
return this;
}
}(jQuery));