Of course there are more complete solutions, but the basic idea on most of them is the same: upload it on one place, sneak into the progress using AJAX on another place.
But HTML5 was here to help us. Wasn't it?
Introducing HTML5 + jQuery + Javascript upload progress!
First the how to use it:- Download it from https://github.com/davidmoreno/jquery-file-upload-progress
- Load jQuery and uploadProgress.js on your html.
- Add this:
$('form').uploadProgress( { onProgress: myprogressbar } ) - Setup your myprogressbar(progress) function, that will be called as file is uploaded.
- Done
This uploadProgress function might be something as simple as a jQuery UI progress bar, and then:
uploadProgress = function(p){
$( ".selector" ).progressbar({ value: p });
}
How it works.
At birds view this plugin uploads the form using XHR, tracks the progress signal (new in HTML5), and when finished, if it cans, replaces current content with the XHR returned content.
Many, really many, things can fail when doing the upload, for example the replacement of the page fails, or the upload fails, or it succeds but returns an error page. And last, but not least, the progress signal might be missing. On all those situations we should at least make it work as in good ol' times, and just forget about the progress. I'm looking at you IE.
How it really works.
Hooking the progress.
jQuery does a great job allowing expansion and customization. We use this availability to replace the built in xhr method on the .ajax function to add the progress bar. It will call the opts.onProgress method with a percentage of completion.
It also hooks other methods to the AJAX query: onBeforeSend, onComplete, and onError.
Finally but not last, its important to send the proper data: new FormData(form); is your friend here.
Getting the answer.
As you know using XHR means AJAX, which in turn is not just loading a page. IT returns whatever this form wanted to do. Normally to show a new page. So I prepared a special function that takes that answer and just replaces current content with that. Its dirty, not always work, but normally is what you want: just show the new page.
It can fail if the CSS is diferent (for example an error is returned), and on some other conditions, so some work could easily improve the behaviour, but normally just works.
If it can not replace the contents, it just do a GET on the POSTed page. If your POST just changes the state of that page, and a reload shows that change (which is algo quite normal), it will also work.
This is implemented at line 18.
This are just the two options I'm using, but actually when you decorate your form with $.uploadProgress, you can also set an onComplete or onError to do different things when completed.
Pros & cons
Pros
- Just works
- Easily customizable
- If something fails, normal post behaviour is preserved
- Uses jQuery
Cons
- Delicate, not work on IE
- Hack to show AJAX sent post. May fail and not show progress.
- Uses jQuery
Clone it!
To clone it:git clone git@github.com:davidmoreno/jquery-file-upload-progress.git
Pull request are welcome!
Thanks
Special thanks goes to DannYo who gave the right tips at http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously-with-jquery.
No comments:
Post a Comment