Multi-file drag and drop AJAX uploads.
I have been using a neat plugin for file uploads recently called ajax-upload plugin. The plugin is written by a web developer named Andrew Valums.
I started out searching for a file upload solution that would fit the following key goals:
- Support multiple files.
- Support drag and drop events similar to GMail (where browser capability permits).
- Degrade nicely when JavaScript is disabled or the browser doesn't support certain features.
- Be jQuery based, because jQuery is awesome.
Anyways, I searched around for ages and couldn't find anything that came close to what I was after. I was just about to start cutting my own solution when came across Andrew's plugin.
The remainder of this post describes my experience using the plugin and loosely how I implemented the plugin. For documentation or downloads of the plugin, I recommend you grab them directly from his website or his GitHub repo.
Here's an example I prepared earlier:
You can upload images up-to 1MB to my website. Fingers crossed they get deleted straight away. ;)
NOTE: you can upload multiple files and drag and drop them (if your browser supports this).
Client side:
Include the external CSS and JavaScript files into your page.
Add the div element to your page with a suitable class/id.
Add some JavaScript code to initialise the plugin on your div element. There are quite a few different options you can set here, start with: element, action, allowedExtensions and sizeLimit. NOTE: allowedExtensions and sizeLimit provide JavaScript (alert based) validation only and should correspond with server side validation using the same set of values.
/**
* File upload example based on the file uploader from:
* http://valums.com/ajax-upload
*/
function fileUpload() {
var $fileUpload = $('#example-file-upload');
if ($fileUpload.length > 0) {
// Set up the FileUploader...
var uploader = new qq.FileUploader({
element: $fileUpload[0],
action: '/uploads/upload',
params: {},
allowedExtensions: ['png', 'jpg', 'jpeg', 'gif', 'bmp'],
sizeLimit: 1 * 1024 * 1024
});
}
}
I have done various implementations of the plugin now, and have been able to style it reasonably well. I use a custom template to provide my own markup to the plugin, in which I include a 'clear list' hyperlink (wired up in JavaScript) to clear out any uploaded list items. I have also had success in using the onComplete callbacks function to display thumbnail(s) of uploaded image(s) dynamically as soon as the images have finished uploading; however to achieve this I did modify the server side code to return a different filename in the JSON response. This is because my server side code renames the files/thumbnails using a unique id based filename scheme.
Overall, the plugin is really quite good. The only thing I could complain about is it not being a jQuery plugin and it's dinky name-spacing.
I mean, common, do I really need to write 'new qq.FileUploader({ ... });'? ;p Just kidding Andrew.
Server side:
On the server side, I used the example PHP code that Andrew provided but wrapped it in a nice CakePHP controller action. His code is largely unmodified, except for a few small tweaks I made to provide more information back to the JavaScript via the JSON response. I stuck his file into my app/vendors folder and just use an:
App::import('Vendor', 'qq_file_uploader');
As I mentioned earlier, my server side CakePHP controller action enforces the validation of file size and extension.
$allowedExtensions = array('png', 'jpg', 'jpeg', 'gif', 'bmp');
$sizeLimit = 1 * 1024 * 1024;
$uploader = new qqFileUploader($allowedExtensions, $sizeLimit);
Unfortunately, I've deliberately left the server side area of my implementation a little bit un-documented... I don't want any dirty behaviour going on. :S
See this plugin out in the wild:
A project I am currently working on is getting ready to go live which makes use of this plugin. Once the website is live I will post a link to it here. * Watch this space. *
Updated (Monday 15th November): The project is now live, check it out at http://duluxpromotions.com.au.
Lastly, a pro tip for GMail users:

In GMail based webmail clients (on browsers that support it), you can drag and drop your attachments into your email composer to upload them. See screenshot above of my work email.