The New Dojo HTML5 Multi-File Uploader

March 21st, 2011 by Mike Wilcox

Dojox UploaderThe latest Dojo download, version 1.6, has just been released. Included is a completely new, HTML5 multi-file uploader, a widget that creates a stylable file-input button, with optional multi-file selection, using only HTML elements. Non-HTML5 browsers have fallback options of Flash or an iframe.

The dojox.form.Uploader is an improvement upon, and replaces the dojox.form.FileUploader. The various problems created by Flash are avoided because it is not used in Mozilla and Webkit browsers. Support for FileUploader will cease as of 1.6, but the code will remain until 2.0 for backwards compatibility.

To handle the different scenarios that a Dojo developer will need, the actual “upload functionality” is handled with plugins. Without these plugins, the Uploader code allows the file-input to be custom styled, and handles the multi-selection in non-HTML5 browsers, using the standard trick of adding a new file-input element after each individual file selection. Pretty much all there is to it is to add a dojoType to a file-input:

<input type="file" multiple="true" dojoType="dojox.form.Uploader" 
	label="Select Some Files" url="/tests/UploadFile.php" uploadOnSelect="true"/>

This will render a button using whatever Dijit style is enabled. In this case, the default Claro:

Uploader Button

Note you would also need one of the uploader plugins for the Ajax upload to work which I will show shortly.

The Uploader also may be placed in a form and will “just work”. Actually, the Uploader will block the form’s submit event and take over its duties of collecting the field values and uploading the data to the server using the form’s action attribute, or the url property given to the Uploader. Remember to set the enctype attribute in your form to multipart/form-data which is used for uploading files.

<form method="post" action="/tests/UploadFile.php" id="myForm" 
	enctype="multipart/form-data" >
		<legend>Form Post Test</legend>
		<input class="browseButton" name="uploadedfile" multiple="true" 
			type="file" dojoType="dojox.form.Uploader" 
			label="Select Some Files" id="uploader" />
		<input type="text" name="album" value="Summer Vacation" />
		<input type="text" name="year" value="2011" />
		<input type="submit" label="Submit" dojoType="dijit.form.Button" />

Uploader Form Example

Again, without a plugin, you are on your own for the actual upload. This is something that is missing from the FileUploader — the ability to just use a styled upload button and post the entire page to the server.

Before getting to the plugins, there is a helper widget for the Uploader. In the scenario above, you could choose several files, but you wouldn’t have any visual indication of what was selected. dojox.form.uploader.FileList automatically connects to an Uploader and detects when files are added, removed, or uploaded, and displays the list. It also has a built-in progress bar that shows during an Ajax upload.

The same code as above, but with the addition of the FileList widget, which has one attribute that points to the Uploader:

<form method="post" action="UploadFile.php" id="myForm" 
	enctype="multipart/form-data" >
		<legend>Form Post Test</legend>
		<input name="uploadedfile" multiple="true" type="file" id="uploader"
			dojoType="dojox.form.Uploader" label="Select Some Files" >
		<input type="text" name="album" value="Summer Vacation" />
		<input type="text" name="year" value="2011" />
		<input type="submit" label="Submit" dojoType="dijit.form.Button" />
		<div id="files" dojoType="dojox.form.uploader.FileList" 

Upload Form Example Files


The Uploader has three plugins available to handle Ajax uploads. The HTML5 plugin deals with the new file-input types in Gecko and WebKit browsers. You then have two options for what to do with IE: the IFrame plugin or the Flash plugin. There’s nothing new or fancy about them; they actually share code with the older FileUploader, albeit simplified.

The IFrame and Flash plugins extend the HTML5 plugin, so you don’t need to require both. And as you may expect, the only time you use the HTML5 plugin by itself is if you have a non-IE project (lucky you!).

In the previous example, the page will change and do a form post to UploadFile.php. To Ajax-ify it, just require one of the plugins:


If you don’t want Flash, even in IE, simply use the IFrame plugin:


So wait… the earlier example used no plugins and was for a straight form; and these plugins are ajaxified but for IE. Where is the HTML5 plugin?

As I said, the Flash and IFrame plugins extend the HTML5 plugin, so it’s included and works automatically. But you could, if you knew that you weren’t using IE… ever… yes, even IE9, which doesn’t include HTML5 form support… include the HTML5 plugin the same way:


Either way, everything is handled automatically. When the “Submit” button is pressed, the Uploader intercepts the onsubmit event and blocks it so the page doesn’t change, grabs the URL from the action attribute, collects all the data in the form fields, and sends everything to the server.


Thanks to a few years of experience working on the FileUploader, I was able to make the Uploader very easy to use and versatile. My previous work with the FileUploader was getting difficult to maintain because the Flash plugin just doesn’t play nicely in any browser other than IE. So while it worked adequately, there were constant and subtle bugs with it in Dijit Tabs or Djit Dialog boxes. Thankfully the HTML5 features in Firefox and WebKit have matured enough that the multi-file-inputs can be used effectively, and the fact that they are native HTML elements means they render without issue.

Be Sociable, Share!

Tags: , , , , , ,

97 Responses to “The New Dojo HTML5 Multi-File Uploader”

  1. Awesome job! Can’t wait to use it!

  2. […] The New Dojo HTML5 Multi-File Uploader   If you enjoyed this article, please consider sharing it! […]

  3. jpe says:

    Mike I saw your post on another page:

    I am reviewing a legacy web page,(in the process of running a new weboptimize test on it), and notice that it has a existing script on the page as follows:

    Do you know if this is a legacy script that google used to provide to embed in a former version of web optimizer? is it safe to remove? and what does it do?

    thank you,

  4. Mike Wilcox says:

    @jpe, I’m not an expert on Google’s code, but yes, utmx is one of their namespaces. I’m guessing it writes a script that loads synchronously.

  5. jpe says:

    Gotcha. Thanks.

  6. skp says:

    Hi Mike,

    Upload works when I create this widget in a template as explained above but when I create it programatically ( new dojox.form.Uploader) the upload post data is empty

    Do we always need to put the widget inside a form? Can you provide some code snippets for programatically creating the Uploader


  7. Mike Wilcox says:

    Hi skp,

    Are you calling the upload method? The submit method expects a form, the upload method can accept an optional object.

  8. skp says:

    Yes Mike,

    I am calling the upload method and not submit as i dont have a form here. I am doing something like this with Flash plugin.

    var div = dojo.create(‘div’,{}),
    input = dojo.create(‘input’,{id:’uploader’, multiple:true, type: ‘file’,label: ‘browse’, name: ‘uploadedfile’, ‘class’: ‘uploadBtn’},div),

    //my uploader
    myUploader = new dojox.form.Uploader({
    label: ‘browse’,
    enctype: “multipart/form-data”,
    multiple: true

    //my dialog to show the widget
    myUploadDialog = new dijit.Dialog({
    title: “Upload Video”,
    style: “width: 400px;height:300px;”,
    content: div


  9. Mike Wilcox says:

    skp, this looks like either a bug or a security “feature” in Firefox. I’ll look more into it.

  10. skp says:

    Thx Mike. the length of inputNode.files is always zero.

  11. Mike Wilcox says:

    I’m getting a files.length, and it’s trying to set the file, but it throws an error. It sounds like I may have found a different bug.

    You can try this if you need it to work now: In the file “dojox.form.uploader.Base”, line 76, change it to: return !dojo.isFF && !!window.FormData;

    This forces the “old” Firefox mode which worked in my tests.

    I’m not satisfied with that – though for the life of me, I can’t see why this problem persists.

  12. skp says:

    If I make the change suggested above, the uploader doesn’t even make a call to the server url. Its failing somewhere even before.

  13. Mike Wilcox says:

    skp, hopefully this code will get you in the right direction. It doesn’t sound like you hit any actual bugs, but I appreciate that you accidentally showed me one!

    var div = dojo.create(‘div’,{});
    myUploadDialog = new dijit.Dialog({
    title: “Upload Video”,
    style: “width: 400px;height:300px;”,
    content: div

    myUploader = new dojox.form.Uploader({
    label: ‘SKP Browse’,
    multiple: true
    var b = new dijit.form.Button({label:”Upload”});


    dojo.connect(b, “onClick”, function(){

  14. skp says:

    This works. So i guess we dont need to add the uploader to an input.
    Thx a lot Mike. Appreciate your help.

  15. eyedrop says:

    Hi Mike,

    I’m trying to use create the uploader programatically and for some reason, it seems the flash uploader.swf doesn’t load in Firefox, while in IE it works. I can’t seem to be able to click on the button in Firefox to bring up the file upload dialog, while it works in IE.

    Looking through Firebug, I don’t see the initializing flash message. I am using Firefox 3.6.16 by the way.

    I’m really out of ideas here. I’ve attach the snippet of code here:

    var uploadDiv = dojo.create(‘div’, {
    id: ‘uploadDiv’
    }, rootDiv);

    dojo.create(‘div’, {
    id: ‘uploadLabel’,
    innerHTML: ‘Select file to upload:’
    }, uploadDiv);

    // Create file uploader button
    var uploadBtn = dojo.create(‘div’, {
    id: ‘uploadBtn’,
    className: ‘uploadBtn’,
    innerHTML: ‘Select File’
    }, uploadDiv);

    var uploader = new dojox.form.Uploader({
    multiple: false,
    uploadOnSelect: false,
    uploadUrl: ‘test’
    }, uploadBtn);


  16. Mike Wilcox says:


    By design Flash doesn’t run in FF or WebKit because the plugin causes problems. It’s going to use HTML5. If you use force=”flash” you could force it.

    Uploader builds its own dijit.form.Button. You are trying to attach it to a button – use a div instead.

  17. eyedrop says:

    Thanks Mike for the fast response.

    Guess my choice of variable name made it confusing, as I was trying different things.

    the ‘uploadBtn’ above is actually a div element.

    I also try attaching it like you told skp, which is uploadBtn.appendChild(uploader.domNode). Didn’t work for me. :(

    I tried using the IFrame plugin and that wasn’t working well either.

    I went to and that is showing up fine.

  18. Mike Wilcox says:

    It looks like what you have should work with the HTML5 uploader. Did you include one of the plugins? Did you insert it in a form? You shouldn’t have to use a form, but there is a bug in the 1.6 release. You also should use the dojox.form.uploader.plugins.Flash plugin, as there is a bug in the IFrame.

  19. eyedrop says:

    so the bug you’re referring to in the 1.6 release, you need to insert it inside a form for it to work (even though you said you shouldn’t have)? Is that what you mean?

    I’ll try to place it inside a form and use the dojox.form.uploader.plugin.Flash plugin also.

    Thanks for the help so far. Appreciate it.

  20. Alex says:

    Hi. I am trying to upload pictures using dojox.form.Uploader and I am somewhat confused about the server side. The documentation is somewhat unclear… I am using Flash plugin and I am testing it on Chrome/Firefox (so I assume it works in HTML5 mode). I don’t really need to pass any information back from the server – I hope that I can rely on HTTP error codes (200 for success and 4xx or 5xx for errors). So, will the Uploader be satisfied if I return HTTP 200, text/plain content-type, and an empty response body? Or should I return some dummy key=value pair to satisfy the case when I’ll be getting requests from IE users (so that they will be sent using Flash)?

    Is there a live demo anywhere that I can look at in HTML5 and Flash/IFrame modes just to see what is sent and what is received?

    In my experiments so far, the file is uploaded and stored fine, but the onComplete does not fire on the JavaScript side…

  21. Mike Wilcox says:

    Hi Alex,

    There are no online demos that actually upload because of security risks. But you can download the Dojo Toolkit and view the tests in dojox/form/tests/. There is an UploadFile.php file that I show for examples and for my testing. You can get even more documentation on the server side from the docs:

    HTTP codes won’t work because Flash has no ability to send or read them.

  22. Alex says:

    Just wanted to clarify something (not a php developer, so its hard to figure out from the code given)

    In html5 case multifile upload case, when server side gets an uploadedfiles array parameter as a part of single request for all the files uploaded, what should the return string look like for several files at once?


  23. Mike Wilcox says:

    Hi Alex,

    An example response looks like this (array of objects returned as json):

    [{“album”:”Summer Vacation”,”year”:”2011″,”file”:”..\/tests\/uploads\/Bobs.png”,”name”:”Bobs.png”,”width”:3200,”height”:2400,”type”:”png”,”size”:5795821},{“album”:”Summer Vacation”,”year”:”2011″,”file”:”..\/tests\/uploads\/Mike.jpg”,”name”:”Mike.jpg”,”width”:480,”height”:480,”type”:”jpg”,”size”:45281}]

  24. Rob says:

    Gerday Mike,

    This is a FYI post.
    I’m not a php person so I went looking for a (classic) ASP solution for the server-side.
    I found one at:

    which took very little time to get going and even less time to get going with the new dojox.form.uploader.
    In trawling the posts on this topic I have found that there are lots of other developers in the same boat (ie, are not php-ofiles) and thought I’d share my new-found gold with them.


  25. Mike Wilcox says:

    Thanks Rob, that kind of information is always welcome!

  26. Rowan says:

    Hi Mike,

    I’m unable to get the HTML5 plugin to call the onComplete handler following a successful upload. I can see in HTML5.createXhr that ‘this.onComplete’ is supposed to be called for xhr.readyState=4 but Uploader.onComplete doesn’t seem to be called at all. I confirmed this by adding an alert in Uploader.onComplete, and found that the alert is never raised. The alert is raised when I force IFrame upload though.

    I’m using dojo-release-1.7.0b2 because that includes fixes for the IFrame plugin.

    Any thoughts?


  27. Mike Wilcox says:

    HI Rowan,

    Is there a return from the server? Is it in error? Do the Dojo tests work for you? Anything different you are doing?

  28. Rowan says:

    Thanks for the quick response Mike.

    I managed to get the Dojo tests running and found that they worked fine, so then set about modifying my code to resemble the test code where appropriate. Unfortunately (fortunately) along the way the problem vanished and for the life of me I can’t reproduce it now!

    Thanks again.


  29. Rowan says:

    Mike, I eventually found the cause. My server code wasn’t enclosing the JSON result in ‘[{‘ and ‘}]’. All working nicely now.


  30. mgn says:

    I’m using dojo-release-1.6.1. The Uploader works fine in a declaratively-created Form. It works in a programmatically-created Form if I perform the submit in the usual way. If, however I catch the submit event and call the uploader’s upload function nothing gets uploaded.

    I’ve copied in the code in Mike Wilcox’s comment of April 14, 2011 at 2:10 pm verbatim into a minimalist test page and this doesn’t work either, again nothing gets uploaded.

    The comment stream above suggests I change line 76 in Base.js. I looked at this, and it doesn’t make sense to change line 76 – it’s a “}”

    It also talks about passing something to the submit funtion – what would that be?
    It also mentions a bug in 1.6 – does that bug still exist in 1.6.1?
    Is there a version of dojo for which Mike’s code is known to work?

    I’m really struggling with this. I eventually managed to get the old uploader to work, catching events to always re-create it when a contentpane was made visible in a tabcontainer, however I couldn’t get flash to pass security credentials in a cookie to Grails Spring Security, whereas HTML does this OK… so I need something that doesn’t need to use flash in either browser.



  31. Mike Wilcox says:


    Sorry this has been so difficult for you. I’m afraid you’ve tripped on a 1.6 bug that is fixed in the trunk, and unfortunately 1.7 is taking a while to release.

    I recommend that you download the trunk (SVN or via a nightly) and copy over the new code. Another unfortunate problem is that 1.7 is refactored to use the AMD loader so it will take some retooling. The SWF is fine, you don’t have to worry about that – just the JS.

  32. Mike Wilcox says:

    @mgn, I’ve uploaded a version of 1.6 code with (some?) 1.7 fixes. A friend of mine did this, so I’m not positive it includes your fix. If not, I may need to cobble something together.

  33. mgn says:

    Hi Mike

    Thanks for getting back to me.
    I downloaded the version at that link and it didn’t seem to fix the problem. I’m fairly convinced I patched it properly. So if I want to take a nightly build as you suggest, what exactly do I need to do to handle the “retooling”. I can’t use flash – because of my cookie problem.


  34. Hi Mike,

    I’m trying to use your new uploader and I have written a test program. I am only at the stage of sending the data to the server, but it is not working, unfortunately. I wonder if you can take a quick look at my code to see if I am doing something obviously wrong or if I am using the Uploader dijit in the wrong way.

    Many thanks,


    These are the errors I get when I call the .upload() method in FF5:
    TypeError { fileName=”http://ajax.googleapis….ojo/1.6/dojo/dojo.xd.js”, message=”evt is undefined”, source=”with(_FirebugCommandLin…eUploader’).upload()\n};”, more…}
    HTML Upload Error:ifd.getElementsByTagName(“textarea”)[0] is undefined
    window[(typeof (djConfig)!=”undefined”….form.uploader.plugins.IFrame);}}};});
    IFrame.xd.js (line 8)
    TypeError: ifd.getElementsByTagName(“textarea”)[0] is undefined
    window[(typeof (djConfig)!=”undefined”…Target;}}_22._finished=true;}};}}};});
    iframe.xd.js (line 8)
    TypeError: ifd.getElementsByTagName(“textarea”)[0] is undefined
    window[(typeof (djConfig)!=”undefined”…Target;}}_22._finished=true;}};}}};});

    and these are the errors in Chrome:
    HTML Upload Error:Cannot read property ‘value’ of undefined
    TypeError: Cannot read property ‘value’ of undefined {…}

    [“value”, undefined]
    “Cannot read property ‘value’ of undefined”
    “TypeError: Cannot read property ‘value’ of undefined\n at\n at _144 (\n at _142 (\n at [object Object]. (\n at Object.resHandle (\n at\n at

    Here is my code:



    var uploader = new dojox.form.Uploader({
    id : ‘fileUploader’,
    label : ‘Select Files to Upload’,
    multiple : true,
    force : ‘iframe’,
    url : ‘uploadcontent.php’

    var fileList = new dojox.form.uploader.FileList({
    id : ‘files’,
    style : ‘background-color: #ddddff; border: solid 1px;’,
    uploaderId : ‘fileUploader’

    var b = new dijit.form.Button({label:’Upload’}, dojo.byId(‘button’));

    dojo.connect(b, ‘onClick’, function(){


  35. Mike Wilcox says:

    David, it could be a few things:

    Most likely, the format from the server is not correct. Check that first.

    Since you’re using Dojo XD, you may need to move the Dojo iframe to a local location and reference it in djConfig with djConfig.dojoBlankHtmlUrl.

    I’m not 100% sure that iframe is supported in Chrome. It’s designed as a fallback for IE. Chrome should use the built-in HTML5 upload.

  36. Hi Mike,

    Thanks for getting back to me. I did have the dojo XD iframe warning, but I resolved that by referencing it as you say. Also, for this work, I only need to have it working in Firefox (in fact, I specifically need it working in Firefox).

    That leaves checking that ‘the format from the server is not correct’. Um… Sorry, but I am not sure what you mean by that? I don’t even see the widget attempting to post/put data. Should I expect to see that in the Firebug console or is that not the case if it is using iframes).


  37. Mike Wilcox says:

    It will be tough to get this right if you don’t have the data from the server getting and returning correctly. I go into detail in the docs: You should also refer to the PHP file I provide in the tests.

    If this is just Firefox, I would turn off force=”iframe”. Use the HTML5 plugin instead. It will work much better, and supports back to FF 3.6 I think.

  38. I had assumed I could at least see the data being sent without getting the PHP file right, but I guess it is more complicated than that.

    I’ll take your advice about HTML5 and I’ll look into testing with the PHP file from your tests.

    Many thanks

  39. David McKechan says:

    Hi Mike,

    So I have put the server side code in place, but nothing is happening with the upload function.
    Here is a pastebin of my test code:

    And here is some stuff from Firebug:
    >>> var x = null;
    >>> dijit.registry.some(function(w) { if( w.declaredClass == “dojox.form.Uploader” ) { x = w } })
    >>> x.getFileList()
    [Object { index=0, name=”P1050663.JPG”, more…}]
    >>> x.upload()

    Sorry if I am missing something obvious or spelt out in the docs, but it seems I need more on the client side?


  40. David McKechan says:

    Hmmm, Since this is FF 3.6 project, I changed
    and I know see the data being sent and it works!

    I thought you said that iFrame inherited HTML5? Who cares though, it’s working for me now! :D

  41. Mike Wilcox says:

    IFrame does, or it’s supposed to. It may be something I need to look at. Glad you got it working!

  42. Jamie Pate says:

    Firefox 6 now supports input[type=’file’].click() to trigger a dialog, it would be nice if this was supported in the next version?

    also why does the fileElement have style information set on the element? this breaks css styling for elements

  43. Mike Wilcox says:

    Good questions Jamie. I’ll keep the click() in mind. I don’t think it will have any changes until 1.8 though. The AMD in 1.7 is slowing things down. I’m not sure about the styling… someone else made some mods, and that may be what happened. I’ll have to look.

  44. Lee Davis says:

    Hi Mike

    I have the uploader embedded in a dialog working like a hot damn in firefox, but as soon we try IE (With the flash plugin) we get the error, “this.flashmovie is null or not an object”. Do you have any suggestions on this one. I’m happy to provide any additional information, just not sure what you might need…


  45. Mike Wilcox says:

    That error is not familiar. Is the SWF loading and accessible (same domain)? Do the DojoX Uploader tests work? Also, a lot of people get the plugins wrong, can you show me how you required the files?

  46. Lee Davis says:

    Yes, the SWF does appear to be loading (after you click through the error dialog) and is in the same domain, however the style is clearly not correct. In fact it still works, but the buttons can only be clicked on their upper edge.

    Regarding the tests, I get an error dojo is undefined, so nothing is working. However I do have a self contained test page that is not embedded in a dialog and it works great. It wasn’t until I put it into a dialog that it became an issue and only with IE (Only tested version 7 so far).


    dojo.require(“dojox.form.uploader.plugins.Flash”); //HTML5 inherited

    [dijit.Dialog], //Superclass – Full Dialog
    href: dojo.moduleUrl(“eim”, “widget/Uploader/content/_uploader.html”),

    Please let me know if there is any other information I can chase down and thanks again for the help!


  47. Mike Wilcox says:

    Lee, I’m not sure what you’re doing there will work, and it’s at least not tested. I have a test for a dialog, although it’s not committed. This is what the HTML looks like:

       Testing uploader is properly created and sized in a Dialog box that is not initially shown.
       Also testing that the dialog can be closed and reopened without losing the file selection.
    <button dojoType=”dijit.form.Button” onClick=”dijit.byId(‘dialog’).show();”>Show Uploader Dialog</button>
    <div id=”dialog” data-dojo-type=”dijit.Dialog” data-dojo-props=’title:”Dialog with Uploader”‘>
       <form method=”post” action=”UploadFile.php” id=”myForm” enctype=”multipart/form-data” >
             <legend>Form Post Test</legend>
             <input class=”browseButton” name=”uploadedfile” multiple=”true” type=”file” dojoType=”dojox.form.Uploader” label=”Select Some Files” id=”uploaderDialog”>
             <input type=”text” name=”album” value=”Summer Vacation” />
             <input type=”text” name=”year” value=”2010″ />
             <input type=”submit” label=”Submit” dojoType=”dijit.form.Button” />
             <div dojoType=”dojox.form.uploader.FileList” uploaderId=”uploaderDialog”></div>

  48. Mike Wilcox says:

    The basic difference between mine and yours is mine has Uploader loading into the document along with everything else. Yours is a lazy load, which I’ve not tested.

  49. Lee Davis says:

    Thanks Mike that is actually very helpful, I didn’t even think about trying everything inline. May be the best approach for now.

  50. Lee Davis says:

    Another question for you, we were running into another issue when we received http error codes 401, 500 for example and were not sure how to handle these. onError, doesn’t seem to fire, so I put a xhr presubmission ping if you will to test the connection, but would like to use uploader exclusively. Do you have any suggestions for handling http status codes other then 200? I’m hoping I’m just doing something wrong.