** 10-01-2013 **
A few weeks back I wrote a blog post about adding image previews for multi-file upload controls. I didn’t mention it at the time but I had an ulterior motive. A reader wrote to me a few weeks before with an interesting question.
Is it possible to use a mult-file input control and let the user select multiple times?
To be clear, what we mean here is that the user selects some files and closes the file picker dialog. She then realizes she forgot a few files and clicks to select them next.
What happens in this situation is pretty simple. Like the multiple select field, if you pick something else then the previous selection is removed. Your only option is similar to what you do for the drop down. Use ctrl/cmd to select multiple files in multiple folders all at once - and don’t screw it up! Obviously most users won’t be able to grok this and will screw it up, even if they know it is possible.
But my experiment had given me an idea. Remember that we can use an event handler to detect changes to the input field and get access to the file data beneath. Here is a code snippet showing this:
using an event handler to detect changes in the files input field
Based on this, my final demo uses this code to create image thumbnails based on pictures you select. My demo has a bug though that meshes well with today’s blog post. If you select images twice, the list of thumbnails grow, but the actual files associated with the control are only based on the last selection. But what if we could take those files and store them?
Before I went down this route, I updated my demo code to use AJAX to post the form. Part of the benefits of XHR2 is the ability to send file data over the wire. Let’s look at a simple example of this.
demo for multiple file select handling
If we focus on the changes, the only real difference is that we have a submit handler for the form. We use a FormData object to package up our form and then post it to a server-side handler. The server-side code isn’t terribly important. It doesn’t see this as anything “special” or “Ajax-y” (my word), it is just a form post. But now the entire process runs through Ajax and not a traditional page reload. (And as a note, I’m not providing any user feedback here. In a real application I’d disable the submit button, tell the user something, etc etc.)
That parts done, now let’s try storing a copy of the files. Here is my updated version with this in action.
storing the files
The changes are pretty simple. I’ve got a new global variable called storedFiles. When I detect a change on the input field, I now push them into this array. Finally, when the form is submitted, instead of pre-populating the FormData object we create it empty and then simply append our files. Note the append call uses the same name, files, so that when the server processes it the name is consistent.
And… believe it or not - this worked. This smells like it may be a slight security concern. I have to imagine that if browser vendors allow for this then it must be safe, but if I used this in production, I’d be real sure to let the end user know what is going on. As I said my previous demo actually implied it was doing this anyway. (I should have been clearing out my thumbnails when you selected files.) I think in that case the user would have expected it.
Related Blog Entries
- Adding a file display list to a multi-file upload HTML control (September 10, 2013)