Creating an asynchronous upload extender
There have been many takes on the asynchronous upload control, but I am presenting another solution that will extend any existing <asp:FileUpload> control.
The basic mechanism to asynchronous upload is to submit the form to a ‘hidden’ iframe:
<html> <body> <form action="http://www.this-page-intentionally-left-blank.org/" method="get" target="winUpload"> <input type="submit" value="Upload" /> </form> <iframe id="winUpload" name="winUpload"></iframe> </body> </html>
In this example, I have declared the <iframe> in the mark-up, and set the form target to the <iframe>. On clicking the upload button, you should see a “blank” page in the <iframe>. This example works in all major browsers.
Since my goal is to create an extender, I need to create the <iframe> and hook up the form taget programmatically using DOM scripting:
<html>
<body>
<form action="http://www.this-page-intentionally-left-blank.org/" method="get">
<input type="submit" value="Upload" />
</form>
<script>
var iframeId = "winUpload";
var iframe = document.createElement("iframe");
iframe.id = iframeId;
iframe.name = iframeId;
document.body.appendChild(iframe);
document.forms[0].target = iframeId;
</script>
</body>
</html>
This example worked in all major browsers except Internet Explorer! With IE, the form is submitted to a new page/tab instead of the <iframe> as specified in the target attribute.
Suspecting that may be the id and name attributes hadn’t been set correctly, I added Sys.Debug.trace(document.getElementById(”winUpload”)) and Sys.Debug.trace(document.getElementsByName(”winUpload”) and the console output shows the <iframe> element, suggesting that the <iframe> was created, attributes set and added to the DOM.
So why can’t the form find its target window? I looked up this problem in a search engine and found a handful of posts:
- http://msdn.microsoft.com/en-us/library/ms536389.aspx
- http://www.quirksmode.org/js/iframe.html
- http://terminalapp.net/submitting-a-form-with-target-set-to-a-script-generated-iframe-on-ie/
- http://news.hping.org/comp.lang.javascript.archive/0959.html
- http://developer.apple.com/internet/webcontent/iframe.html
- http://readystate4.com/2008/05/13/dynamically-creating-an-iframe-for-internet-explorer/
Using the suggestions from these posts, here is the updated example:
<html>
<body>
<form action="http://www.this-page-intentionally-left-blank.org/" method="get">
<input type="submit" value="Upload" />
</form>
<script>
var iframeId = "winUpload";
if (document.all) {
var iframe = document.createElement("<iframe id='" + iframeId + "' name='" + iframeId + "'>");
} else {
var iframe = document.createElement("iframe");
}
iframe.id = iframeId;
iframe.name = iframeId;
document.body.appendChild(iframe);
document.forms[0].target = iframeId;
</script>
</body>
</html>
B.t.w. If you are not using ASP.NET AJAX, why not take a look at YUI’s Connection Manager which implements asynchronous file uploads.
!!! To be continued !!!