Skip to content

Instantly share code, notes, and snippets.

@andrevinsky
Last active November 21, 2017 11:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save andrevinsky/5856405 to your computer and use it in GitHub Desktop.
Save andrevinsky/5856405 to your computer and use it in GitHub Desktop.
( function($) {
$.fn.uploadFile = function(options) {
ajaxFileUpload(this.filter(':file'), options);
return this;
};
function ajaxFileUpload(elements, s) {
s = $.extend({}, $.ajaxSettings, s);
var id = new Date().getTime(),
form = createUploadForm(id, elements, s.url, s.data),
frame = createUploadIframe(id, s.secureuri);
var frameId = 'jUploadFrame' + id;
// Watch for a new set of requests
if (s.global && !$.active++) {
$.event.trigger("ajaxStart");
}
// Create the request object
var requestDone = false, xml = {};
if (s.global)
$.event.trigger("ajaxSend", [xml, s]);
// Wait for a response to come back
var uploadCallback = function(isTimeout) {
var io = document.getElementById(frameId);
try {
if (io.contentWindow) {
xml.responseText = io.contentWindow.document.body ? io.contentWindow.document.body.innerHTML : null;
xml.responseXML = io.contentWindow.document.XMLDocument ? io.contentWindow.document.XMLDocument : io.contentWindow.document;
} else if (io.contentDocument) {
xml.responseText = io.contentDocument.document.body ? io.contentDocument.document.body.innerHTML : null;
xml.responseXML = io.contentDocument.document.XMLDocument ? io.contentDocument.document.XMLDocument : io.contentDocument.document;
}
} catch(e) {
handleError(s, xml, null, e);
}
if (xml || isTimeout == "timeout") {
requestDone = true;
var status;
try {
status = isTimeout != "timeout" ? "success" : "error";
// Make sure that the request was successful or not modified
if (status != "error") {
// process the data (runs the xml through httpData regardless of callback)
var data = uploadHttpData(xml, s.dataType);
// If a local callback was specified, fire it and pass it the data
if (s.success)
s.success(data, status);
// Fire the global callback
if (s.global)
$.event.trigger("ajaxSuccess", [xml, s]);
} else
handleError(s, xml, status);
} catch(e) {
status = "error";
handleError(s, xml, status, e);
}
// The request was completed
if (s.global)
$.event.trigger("ajaxComplete", [xml, s]);
// Handle the global AJAX counter
if (s.global && !--$.active)
$.event.trigger("ajaxStop");
// Process result
if (s.complete)
s.complete(xml, status);
$(io).off();
setTimeout(function() {
try {
$(io).remove();
$(form).remove();
} catch(e) {
handleError(s, xml, null, e);
}
}, 100)
xml = null;
}
};
// Timeout checker
if (s.timeout > 0) {
setTimeout(function() {
// Check to see if the request is still happening
if (!requestDone)
uploadCallback("timeout");
}, s.timeout);
}
frame.load(uploadCallback);
try {
form.submit();
} catch(e) {
handleError(s, xml, null, e);
}
}
function createUploadIframe(id, uri) {
//create frame
var iframeMarkup = [
'<iframe id="jUploadFrame', id, '" name="jUploadFrame', id, '" style="position:absolute; top:-9999px; left:-9999px" ', getSrc(uri), ' />'
].join('');
return $(iframeMarkup).appendTo(document.body);
}
function getSrc(uri) {
if (window.ActiveXObject) {
if ( typeof uri == 'boolean') {
return ' src="javascript:false" ';
} else if ( typeof uri == 'string') {
return ' src="'+uri+'" ';
}
}
return '';
}
function createUploadForm(id, elements, url, data) {
//create form
var fileId = 'jUploadFile' + id,
formMarkup = [
'<form style="position: absolute;top: -1200px;left: -1200px;" action="', url, '" method="POST" name="jUploadForm', id, '" id="jUploadForm', id, '" enctype="multipart/form-data" encoding="multipart/form-data" target="jUploadFrame', id, '"></form>'
].join(''),
form = $(formMarkup);
$.each(data || {}, function(k, v){
$('<input type="hidden" name="'+ k + '" />').val(v).appendTo(form);
});
elements.each(function(i){
var source = $(this), substitute = source.clone(true, true);
source.attr('id', fileId + '_' + i);
substitute.insertBefore(source);
source.appendTo(form);
});
return form.appendTo('body');
}
function uploadHttpData(r, type) {
var data = !type, type = type.toLowerCase();
data = type == "xml" || data ? r.responseXML : r.responseText;
switch (type) {
case 'script':
// If the type is "script", eval it in global context
$.globalEval(data);
break;
case 'json':
// Get the JavaScript object, if JSON is used.
eval("data = " + data);
break;
case 'html':
// evaluate scripts within html
$("<div>").html(data).evalScripts();
break;
}
return data;
}
function handleError(s, xhr, status, e) {
// If a local callback was specified, fire it
if (s.error)
s.error(xhr, status, e);
// Fire the global callback
/* INCOMPATIBLE!!! Modern jQuery 1.5+ expects xhr to be an jqXHR object.
if ( s.global )
$.event.trigger( "ajaxError", [xhr, s, e] );
*/
}
}(jQuery));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment