One of the features I wanted to include in our new CMS system was the ability for users to upload files via AJAX, without using a form post to reload the page, and so that they can begin uploading a new file while an upload is already in progress.
JQuery to the rescue!
The plugin does the following things:
- Sets up the form so that when the user submits, an invisble iframe is added to the page, and the form post is sent to that
- Your back-end programming (PHP in my case) outputs some info as JSON to indicate whether the upload was successful
- The plugin polls the iframe until it has loaded and found some data
You can use the plugin by attaching it to an HTML upload form as so:
$('#myUploadForm').ajaxUpload({
onComplete : function(data) {
// data is the JSON output from your PHP script
}
})
The following callbacks can be passed in:
- onStart: this is called first, right when the user clicks the ’submit’ button
- loading: this is called next, when the form has been posted and we’re waiting for the upload to complete
- onComplete: this is called when the upload has been completed, and received the JSON output from your backend script as its argument
You can download the script here, or here it is below too:
/**
* Author: James Carmichael
* www.siteclick.co.uk
*
* If you use this plugin in your project, please kindly consider linking to the above
*
* JQuery ajax upload plugin
*
* v0.1 22/06/2008
* v0.2 01/05/2009 Added 'onStart' function to settings, so upload start can be detected
*
* License: MIT
*/
jQuery.fn.ajaxUpload = function(settings) {
// Set defaults
var settings = jQuery.extend({
'loading' : function() {},
'onComplete' : function() {},
'onStart' : function() {},
'type' : 'json'
}, settings);
var _this = this;
// For each item
return this.each(function(){
jQuery(this).submit(function() {
// Do onStart function
settings.onStart(this);
// Make up a number
var iframeId = 'upload_' + Math.round(Math.random() * 1000000);
// Create iframe for data transfer
var iframe = jQuery('<iframe name="' + iframeId + '" id="' + iframeId + '"></iframe>');
jQuery(document.body).append(iframe);
jQuery(iframe).hide();
// Set form action attribute
jQuery(this).attr('target', iframeId);
// Call the loading function
settings.loading();
/**
* Function to poll iframe every second
*/
_this.pollIframe = function() {
// Get iframe HTML
var html = jQuery('#'+iframeId).contents().find('body').html();
// Data blank - try later
if(!html) {
window.setTimeout(_this.pollIframe, 1000);
return;
}
// We have some data - send it to the oncomplete function
switch(settings.type) {
case 'json':
var data = eval('('+html+')');
settings.onComplete(data);
break;
}
// Discard the iframe
jQuery('#'+iframeId).remove();
}
// Begin polling
window.setTimeout(_this.pollIframe, 1000);
})
})
}