The Dojo Toolkit Multi-file Uploader September 2nd, 2008 at 12:02 am by Mike Wilcox

The Dojo Toolkit now has support for multi-file uploads, thanks to the new Deft project. The dojox.form.FileUploader class embeds a hidden SWF file in the page which, when triggered, will open a system dialog that supports multiple file selection, and also file masks, which allows the user to filter their selection by file type.
Better yet, it’s fully degradable. If the user does not have version 9 or greater of the Flash Player installed it can, depending on the options you set, present the user with a standard HTML file input instead (or the option to install the latest Flash Player). The HTML form also supports multiple files, although due to browser restrictions, only one can be selected at a time. But they are all uploaded at once.
A major benefit to developers is the flexibility to supply your own styled upload button. For example, a paperclip icon toolbar button in an email application should not look like the standard file input with a text field followed by a “browse …” button. What inspired this design was working on projects where designers and clients would hand me a specification which would say, “the upload button looks like this“.
dojox.form.FileUploader will be in the new 1.2 version of the Dojo Toolkit, which will be released in September. In the meantime, it can be downloaded from one of the nightly builds.
dojox.form.FileUploader
dojox.form.FileUploader is a simple wrapper class. It accepts your parameters, does a little plugin detection, and determines which uploader is necessary: dojox.form.FileInputFlash or dojox.form.FileInputOverlay.
Here is the example usage instantiating the FileUploader:
var uploader = new dojox.form.FileInputFlash({ uploadUrl:"http.localHost/FileUpload.php", button:myButton, uploadOnChange: false, selectMultipleFiles: true, fileMask: ["All Images", "*.jpg;*.jpeg;*.gif;*.png"], degradable: true });
There is only one method: upload(), but there are also events:
- onChange - Fires when a file or files are selected
- onProgress - Supplies the current information of each file’s upload progress (Flash only)
- onComplete - Fires when the file or files have been uploaded
- onError - Fires during connection problems such as file not found, etc.
dojox.form.FileInputFlash
The FileInputFlash Deft component is installed with dojox.embed.Flash. It is displayed with the minimum 1 pixel x 1 pixel and tucked in the upper left hand corner, so it’s not noticeable but will still be activated by browsers that require the SWF to be on screen. Upon initialization, FileInputFlash connects your button to the browse method within the SWF, so clicking the button will open the system dialog.
dojox.form.FileInputOverlay
The FileInputOverlay API is identical to that of FileInputFlash. It has a couple of differences:
- it does not fire onProgress (without some server side magic)
- in the case of
selectMultipleFiles = true, the user can’t select multiple files, but can continue to add to the file upload list by clicking the upload button.
Styling FileInputOverlay
The FileInputOverlay was filled with challenges. Standard browser file input fields can’t be modified or styled, and are engineered with security restrictions - restrictions that follow early browser implementations rather than the W3C specification or HTML5 drafts. The restriction is designed to prevent uploading a user’s files without their knowledge, like C:/passwords.txt — which is precisely where I keep all of my passwords.
My project started with the now-standard technique originated by quirksmode, of creating the desired button, then floating the real browse button over the desired button, set it’s opacity to zero, and then conform to the size of the desired button by applying the clip style to the browse button.

In order for this implementation to handle an upload button of any size, I needed to set the style of the file input equal to the size of the upload button. Enter Problems with Internet Explorer Mode. Although to be fair, all of the browsers have their challenges.
To accommodate large buttons, the size of the file input had to be big enough to cover the desired button. But again, due to restrictions, changing the height, width, and font-size yielded results like this:

Figure A
The height, width, and font-size of the text field was changing, not that of the button (although it affected the height). However, after some trial and error, I discovered that setting the font-size using em units works (font-size:5em):

Figure B
Bingo. So now all that’s left is to set the style, and we’re good, right? Wrong. It seemed that the em trick works only from a cssRule in a style sheet or style tag. Applying the em trick in JavaScript with the style property again leaves us with the results from Figure A. This wouldn’t be a problem in a legacy application, because we’d know what size we wanted the button to be. This is not the case for a JavaScript toolkit.
I could have just made every file input huge, with 10 ems or something, but that seemed dirty. To fix this, I reintroduced (and refactored) the dojo.style package from Dojo 0.4.3, as dojox.html.style. For this purpose, we only need the dojox.html.insertCssRule() method to create the style in a dynamic style sheet before creating the input element.
Final Note: button.click()
In several forums I’ve read that IE is capable of triggering a button through code, with the element’s click() method. I had a client with a requirement for Internet Explorer only. So I thought this would be a neat solution; avoiding the (as yet unwritten) complex patterns above.
The Demo
You can see a demo of the FileUploader in action.
Summary
It took a long time for the Dojo Toolkit to finally have it’s multi-uploader, but I think the wait was worth it. The Deft project make the FileUploader code for the SWF visible, and it can therefore be fixed or amended by contributors. The HTML portion of the uploader code has gone through months of iterations, so it should accommodate most situations.



Posted September 4th, 2008 at 8:09 am
[…] continues their work on Deft with a multi-file uploader: The Dojo Toolkit now has support for multi-file uploads, thanks to the new Deft project. The […]
Posted September 4th, 2008 at 11:11 pm
Very nice. You should also include an example that has a progress bar.
Posted September 5th, 2008 at 10:49 am
Does this Multi-file uploader handle the Flash 10 changes that only allow the opening of the Flash File browse on Flash based click?
http://theflashblog.com/?p=423
Posted September 5th, 2008 at 11:25 am
How are the files sent, and what are the post query parameters of the files?
I need something like this, but I need to be able to plug into a specific upload API that needs inputs like
?image0=[]&image1=[]
Posted September 5th, 2008 at 12:40 pm
@Matthew: In a word, no. I’ll probably implement the Google Gears uploader first before I fix Adobe’s security *enhancement*
@Hunter: You’ll find in my test php file, UploadFile.php:
Flash fieldname: Filedata
HTML fieldname: uploadedfile
HTML multi fieldname: uploadedfile[number]
The HTML multi mode would handle what you request - the fieldname can be changed as a property.
For Flash though, it’s a bit problematic. The fieldname can be changed, although that is not implemented here. Also, Flash actually uploads to the server one at a time, not all at once with numbered fieldnames. Not sure if it could be manipulated to change the fieldname on each upload. I’d think not.
Posted September 11th, 2008 at 12:02 am
[…] using the Deft project, I created a multi-file uploader Flash component for DojoX. It uses a typical design pattern—embed a hidden SWF in the web page, and with the […]
Posted September 23rd, 2008 at 3:42 am
MultipleFileUpload widget is very nice. I have a question regarding this widget.
Once we selected multiple files , can we remove some of them before uploading?
Posted September 23rd, 2008 at 7:28 am
@vinu:
Thanks, and that’s an interesting question. The short answer is no. Looking at the Flash documentation, there is a FileReference.cancel() method that stops the upload. Whether this stops it before it starts I’m not sure. It would require experimentation.
Posted October 13th, 2008 at 7:57 am
Hi there,
i tried to use this widget but everytime i hit the upload button i get the following error:
this.flashMovie is undefined
any i dea whats wrong there?
This is how i define the widget:
fileUploader = new dojox.form.FileUploader({
button:dijit.byId(”btn0″),
degradable:true,
uploadUrl:”content-flow?execution=${flowExecutionKey}&_eventId=uploadFile”,
uploadOnChange:false,
selectMultipleFiles:true,
fileMask:[”All Files”, “*.*”],
isDebug:true
});
Posted October 14th, 2008 at 3:02 pm
I’m having a similar problem. The demo (https://user.sitepen.com/~mwilcox/dojotoolkit/demos/uploader/demo.html) works fine for me, but if I copy it to my machine (along with src.js and demo.css), and I change the referenced Dojo to http://o.aolcdn.com/dojo/1.2.0/dojo/dojo.xd.js, it doesn’t work. FireBug gives errors:
this.flashMovie.setFileMask is not a function
this.flashMovie.openDialog is not a function
this.flashMovie.doUpload is not a function
The same thing happens if I try this with the nightly test (http://archive.dojotoolkit.org/nightly/dojotoolkit/dojox/form/tests/test_FileUploader.html)
Posted October 27th, 2008 at 8:21 am
Hi,
I have tried to use your demo with dojo 1.2, but the onComplete event doesn’t seem to be fired.
Is there a difference between dojo 1.1 et 1.2 ?
thanks
Pascall
Posted October 27th, 2008 at 8:56 am
@Rozik, fgamador, pascall:
I’m having trouble reproducing your errors. It would be enormously helpful if you could create a test file or the steps to reproduce, and file a bug at http://bugs.dojotoolkit.org/ - cc: mwilcox.
I assure you all that I am especially concerned with the communication errors to the flashMovie, and would like that part in particular to be as trouble-free as possible.
@pascall:
his has not been tested on the CDN - it may cause some timing issue with the load, I’m not sure. The Uploader is technically part of 1.2 and was not in 1.1 - it’s release date made it look like that though.
Posted October 27th, 2008 at 9:13 am
Hi,
thanks for your answer,
I have tried to connect to http://bugs.dojotoolkit.org/ , i cannot reach to connect myself.
For my test, i use the same html and src.js as yours in https://user.sitepen.com/~mwilcox/dojotoolkit/demos/uploader/demo.html, so it’s easy to reproduce.
thanks
pascall
Posted October 27th, 2008 at 9:26 am
@pascall
The Trac on Dojo is a little finicky. You may have to try a few times. Log in with user:guest, pass: guest.
However, first check your permissions. I’m using the exact same code on my machine (sans the CDN) and it works - but I have to set the folder permissions for “uploader” and “UploadedFiles” to read, write and execute (execute may not be necessary) - and I also needed to set the owner (on my Mac) to _www. I can’t remember what it is, but there is a PC equivalent to give “system access”.
Posted October 27th, 2008 at 12:27 pm
In fact, the upload works, files are uploaded on the server but which is not working, is the onComplete even after which, in your demo, the image appears on the right and its name appears in the textarea for removal.
Progress event works fine, from 0 to 100%, but after 100% nothing appends.
Posted October 28th, 2008 at 1:51 am
Hi,
i have another trouble. The same script (html,js) have 2 different behaviors at work or a home, with FF3.
At work, uploader.swf is loaded and works fine, on click a window appears asking for images, but at home flash is not loaded, and i have and input type file instead of (as your example above )
Both computers are on FF3, with the same flash plugin version.
you can see it on http://test.mrbinr.com/testDojo/uploader/demo.html
I still cannot reach to connect myself to http://bugs.dojotoolkit.org/ and i have the same problem with my identification on dojotoolkit for which i always have to ask for new password. (its really strange..)
Posted October 28th, 2008 at 2:36 am
oups, sorry, i check flash plugin version, and at work its Flash 9.0 r124 and at home it’s 10, i think it’s why behaviors are different.
Posted October 28th, 2008 at 8:52 am
hi, i have installed Flash player 10 at work, and your script does not work anymore on FF3.
Into FF3, if you click on ‘Select images’, an error is sent into firebug :
[Exception… “‘Error calling method on NPObject! [plugin exception: Error in Actionscript. Use a try/catch block to find error.].’ when calling method: [nsIDOMEventListener::handleEvent]” nsresult: “0×8057001e (NS_ERROR_XPC_JS_THREW_STRING)” location: “” data: no]
Line 0
May be it can help you…
I have tried under IE7, and it works.
Posted October 29th, 2008 at 10:25 pm
Hi -
I was wondering where I may be able to find the src.js source to your example since I cannot seem to find it. I am looking on simply using the multi-file html form handling mechanism that the dojox.form.FileInputOverlay provides.
Thanks
Nick
Posted October 30th, 2008 at 5:36 am
There are plans to make the Demos publicly available, but in the meantime, you can access them here:
http://download.dojotoolkit.org/current-stable/dojo-release-1.2.0-demos.tar.gz
BTW: The Uploader does not work with Flash Player 10. I mention that in my next blog but not this one. It’s a high priority for me to make it compatible, but I haven’t yet had a chance.
Posted November 18th, 2008 at 6:30 am
Hello !
If you need to upload multiples files you can also use a flash uploader like NAS Uploader.
examples and source codes here
http://www.nasuploader.com
bye