STOP PRESS: There is now a new version here, based on Mootools.
Please note: As you will notice if you take the time to read this article, you will see no mention of the word ‘Ajax’ (apart from the ones in this paragraph). That’s because this technique has nothing whatsoever to do with Ajax — and I never claimed that it did. The fact that people are linking to this page and suggesting some sort of Ajax-y connection has nothing to do with me. So please, no more “but it’s not Ajax!” comments.
10th October 2005: Updated to add Safari support. Many thanks to Luis Torrefranca, Jamie Butler and Matt Kurpiewski (http://www.law.pitt.edu) and Shawn Parker & John Pennypacker (http://www.fuzzycoconut.com) for their help. Please download again.
2nd October 2005: I updated the script to fix a potentially nasty bug.
I was mulling over some ideas while walking home from work last week, when I came up with what I thought might be a quite cunning (and more atttractive and useable) way to allow a form to use a single file input element — sort of — to upload multiple files. Since you can only store file upload information in a file upload element (<input type=”file”>), you’ll always need to have one element per file to be uploaded. But what occurred to me is that you don’t need to display all those file elements.
Using the DOM, it’s actually a relatively simple matter to conceal a file element once a file has been chosen, and add a new (empty) one in its place. And to keep doing so, as many times as you like. It all happens so quickly, that it appears that there’s only one input element.
To make it even smarter, you can then read the value of each element (ie. the name of the file to be uploaded) and build a list, in whatever format you like, of chosen files. And with a little bit more code you can add the ability selectively to remove files that have been picked.
Enough waffling — here’s a demonstration:
I’ve deliberately left all styling out of the class, so the list is ugly (you can edit this yourself quite easily). And obviously there’s no submit button (I don’t want a load of junk files uploaded to my host, thanks) so I can’t show it ‘in action’ as such. You’ll just have to take my word for it, that it really does work. Or of course, download the (zipped) file and try it for yourself (don’t use the version included in this page, it’s slightly different).
The code is heavily commented to explain a) how to use it and b) how it works, although I’ve also included a compressed, comment- and whitespace-free version which is significantly smaller. I’ve tested it successfully with Mozilla Firefox 1.04, MSIE 6 and Opera 8 but I’m fairly confident that it’ll work with most, if not all, modern DOM-enabled browsers — if you can confirm or disprove this, please let me know.
One thing to be aware of when allowing mutliple uploads is that there are generally limits on the quantity of data that can be sent in any one request — for example, PHP has a default limit of 2MB (although this can be changed, using ini_set(‘upload_max_filesize’, ‘[new size]M’) where new size is the maximum number in megabytes — this will not work if safe mode is enabled on your host).
If you’re looking for help handling the files once they’ve been uploaded, you could do worse than take a look at this this comment by Shawn Parker (thanks again, Shawn!).
The licence for this code is simple: use it how you like, but don’t blame me if it breaks anything. Also, it’d be nice if you’d leave the credit (with the link to this site) in the code.