Monday, December 18, 2006

SWFUpload

There is a fundamental problem with File Uploads in web browsers. If there is anything that is going to cause the file to be invalid you can't let the user know until after they have uploaded the entire file.

"Life Sucks" Rant
If the file is of the wrong type, wrong size, or doesn't meet some of other criteria it doesn't matter. The browser happily sends the complete file to the web server. Then you can check out the file and return some sort of status message.

Great! My user, in his remote village (I live in Alaska) gets on his Dial-Up, or uses the slow satellite connection at the local community center. He attaches his 20MB resume, waits 20 minutes while it uploads and then gets a nice message back saying: "The file was too big. You just burned away 20 minutes of your life. Would like to burn away another 20? Please try again."

Wouldn't it be great if the browser could let me know a little bit about the file before it's uploaded? The browser allows Javascript to see the full file path. Would it risk national security to give me the file size?

I've looked in to a few solutions. We are an ASP.Net shop and I checked out a couple controls that do file upload progress and file size check, etc. They are nifty but don't really cut it. They are too fragile. And I don't want to fix one problem while introducing a dozen new ones.

It turns out that since Flash 8 you can do uploads via the browsers Flash Plugin and so I discovered SWF Upload. It's pretty nice and avoids some of the pitfalls that the other "browser only" solutions have to face.

I've been trying to integrate the thing with ASP.Net 2.0. There are some issues. I'm pretty proficient at Javascript and worked around some bugs. It seemed to be going well. Now I just have to deal with the issue of having a separate page hit for receiving the files and tying that back to the form the user is completing right now.

Everything seemed rosy. However, today, the thing just stopped working and always returns an IOError. Even the unmodified sample code stopped working.

Oh well. I guess I'll just wait until the browser vendors fix the File control.


Getting SWFUpload to work in ASP.Net

SWFUpload returns an error if you try to wedge the thing inside the <form runat="server"> tags. This has to do with the way things get arranged inside the DOM when the Flash is dynamically added to the page.

My solution was to change the Javascript that SWFUpload uses to add itself to the page. Instead of adding itself in the "target" it needs to add itself to the "body".

This can be done by modifying the mmSWFUpload.js file. Find the line:

n.innerHTML = this.getSWFHTML();

in the "write" method and replace it with this:

var body = document.getElementsByTagName("body")[0];
var container = document.createElement("div");
body.appendChild(container);
container.innerHTML = this.getSWFHTML();

There you go. That'll do it. The SWFUpload flash object is added outside the FORM tags and works correctly. Good luck with the rest.

9 comments:

  1. Anonymous10:52 AM

    Hi, nice post! I did your change and worked well. I was wondering you found how to add more than one SWFUpload to a page?? Thanks in advance...

    ReplyDelete
  2. I've kinda of given up on SWFUpload. My development system has started acting up (first uploads failed, but now SWFUpload won't load at all).

    So, until I rebuild my system (probably won't happen soon) I don't know that I'll get back to SWFUpload.

    I did re-review the SWFUpload Javascript code and I think you could modify it to allow multiple, separate SWFUploads to be loaded. You need to make it so where it creates an element with the ID _mmSWFUploadField with a variable that gets created each time you call "init" then it will probably work.

    However, a single SWFUpload will allow multiple file uploads (even selecting multiple files at a time). I think it would be easier to either come up with a way to use a single upload field or split your multiple uploads to different pages. That way you don't have to fiddle with complicated Javascript.

    I'm still looking in to it. I'll make a post soon if I work it out.

    ReplyDelete
  3. Anonymous11:39 AM

    Hello again...

    I did exactly what you said (used a variable for the id too) and the script wrote different < a > elements with different ids (even wrote different embed elements with different ids) and the href of the < a > element called each his embed.

    but...

    It didn't work, when I click the < a > element it would said the embed element didn't had that function and didn't work, so I gave up, and worked another solution for my interface (single swfupload).

    If you come up with a solution please let me know.

    Did you know of any other code similar to SWFUpload that I could use??

    thanks again..

    ReplyDelete
  4. I worked on this last night. We probably made very similar changes. I got a similar errors and it didn't work. Then it was time to go to bed.

    I believe the problem comes down to the way the SWFUpload is designed. They use Javascript associative arrays to build a static class. This means you can't do:

    var swfupload1 = new mmSWFUpload();

    It means all the settings and values are shared with the Global object and you can't create a second distinct instance.

    I think the code needs to be re-structured so you can create instances of swfUpload objects. I'm going to give it a shot today and I'll post my results.

    Unfortunately this isn't a "change the code on lines 10 and 11" kind of deal. This is a "it's the same code but different, replace this file" kind of change.

    ----

    I've looked at a couple other flash upload tools and SWFUpload seems pretty good. But like I said, it's really the browsers that need to change.

    ReplyDelete
  5. Anonymous5:18 PM

    I think that is the problem too, but I didn't tray to change anything because I'm in a hurry with this project :P

    well thanks again any way ...

    I'll be checking your post later to see if you got something..

    Good luck!

    cya

    ReplyDelete
  6. I've made some good progress. I have loaded 2 SWF upload thingies. They both display the file dialog. In IE it then doesn't update the display. In Firefox it show the progress bar but after a few uploads it still adds the file but doesn't show a progress bar and my I never get the "Queue Done" message.

    I'll post my write up and code tomorrow.

    I'm probably not going to use SWFUpload. It was an interesting side project but I need to get back to my other projects.

    ReplyDelete
  7. Anonymous2:06 PM

    The code on this page does not work. Completely waste of time.

    ReplyDelete
  8. Kind of like posting constructive comments on blogs?

    ReplyDelete
  9. Anonymous8:25 AM

    i agree, wasted whole day ons this crap

    ReplyDelete