The group is just starting (2nd meeting), so there were only a few people, but as some of them looked quite interested by my talk, and some other couldn’t come due to personal or professional duties, I thought I could write a couple of blog posts about the same topic.
I choose File Upload Form example because it’s standalone, frequently used and it can be improved by many ways with HTML5 APIs.
- Using feature detection for progressive enhancement
- Using loosely coupled modules to architecture web applications.
This post focus on the first part of the talk.
It presents the feature detection technique.
I’ll cover the second part, loosely coupled modules, in another article.
If you’re in a hurry, or simply don’t want to read the whole post, you’ll find the slides embedded below and everything else on Github:
The talk was in French so the slides are also written in French, even if it uses a lot of English keywords.
The main idea in progressive enhancement is to provide an application that work in any context.
A good approach is to start development with features that will work (quite) everywhere, and progressively add more specific features to improve your application’s user experience in modern browsers.
Talking about file upload form, our starting point is a simple HTML markup.
On the other hand, it requires a full page reload so the first thing to do to bring some hype in this is to allow uploading the file with an asynchronous request.
Uploading a file trough an asynchronous request isn’t that easy.
The FormData API perfectly fits our needs but it’s not well supported across all browsers (IE, I’m looking at you… See Browser_compatibility section).
Remember that our main concern is to provide the best user experience on each browser.
So how do we upload a file asynchronously in a browser that don’t support
Answer is by using an
Please note that I started by creating a jQuery plugin to make the code more easily reusable.
I also hid the submit button and the bound event ‘onchange’ on the input field to submit the form.
The following code snippets come from step1/upload.js file.
First, we have to listen to the
submit event to prepare the form:
Next, let’s append an hidden
iframe to the form and define the
target attribute to match the
Once done, the form can be submitted as usual, the server’s answer will be loaded into the
However, due to security concerns, we won’t be able to read the
iframe content once loaded, so we also need to create a callback function and to send the function name to the server as a URL parameter.
This way, the server script will be aware that we are using an
iframe and will be able to generate the appropriate response.
Knowing that the server response will be loaded as
iframe content, the server script has to generate this small piece of HTML.
It includes a
script tag, witch calls the
callback function on the parent window. The json
result is send as a parameter of that function.
Here we are.
Our script can send files asynchronously, without reloading the whole page, and it even works with old browsers.
Of course, we could decide to stop there, but we won’t because of the following:
- No Error handling: if something goes wrong while sending the file, or if the server don’t render the good response, the callback function will never be called, and we can’t handle the error.
You probably want to add a timeout to the script above to avoid waiting for an answer that would never come.
- It’s not AJAX.
You probably already notice this point.
We are faking it.
The form is still sent as HTML form, we only changed his target.
The file is uploaded asynchronously, but without any XmlHttpRequest involved.
- It’s dirty.
I’m OK as it stays a fall-back solution, but keeping it as the main implementation? Yuck!
Time to do things the right way? OK. Let’s start by editing the submit event listener as following:
this.$upload variable represents a jQuery object containing the
input[type=file] DOM node (see the complete step2/upload.js file for more details).
Here we have to check if the browser supports both
If these two conditions are satisfied, we can go with the “HTML5” file upload.
Otherwise, we just fall-back to the
iframe hack… Simple isn’t it?
This is Feature Dectection and it’s one of the key concepts of modern web development.
It’s the only way we have to use the latest HTML5 features without breaking old browser’s support.
Now, we’re sure that we can use
FormData upload, we just need to implement the method as shown in the following code extract.
As you can read, it’s way simpler and less hacky compared to the
Server response and errors are handled the same way than with any other ajax request.
We’re done for part 1.
In the 2nd part, I explain how to handle the thumbnail associated to the file input field.
It’s a very good example to introduce loosely coupled modules, and to show some other uses of the feature detection technique.
File Upload Form - Part 2: Loosely Coupled Modules