Implementing single-page web applications that work on all browsers remains a challenge. For the basic task of uploading files, you still need some sort of polyfill or library that adds support for older browsers (read IE 8 and 9, which are still in wide use).

In this tutorial I’m going to describe how to integrate one such library, called mOxie, with one client-side MVC framework, called Ember.js.

0. Getting the mOxie library

I’m going to assume you already have an Ember app going, so the first step is acquiring the mOxie files. You can either use the pre-built files or compile your own. For example, we won’t need XHR2 support in this tutorial, so we can leave it out.

1. Defining the template

The next thing we have to do is write the Handlebars template that will contain all the UI elements we need:

The UI has several components:

  • error and progress notifications
  • the list of selected files
  • the button for selecting more files
  • the button for initiating the upload

2. Initializing the file picker

In the template above we placed the button inside a view. We can use that view to convert the <button> into a file picker:

Here we create a mOxie.FileInput instance once the template containing the button is rendered.

3. Adding/removing files

The view we defined in the previous step will send events up to the controller, which has to respond to them:

The neat thing about Ember.js is that it will automatically re-render the template whenever the attachments property is modified.

4. Uploading the files

Finally, when the user wants to submit the form, we have to actually send the files to the server:

We start uploading all the files concurrently. When one is done, we increment a counter. When all of them are done, we clear the queue. Did I mention promises are great?

And here are the helper functions used in the controller above:

I wrapped both the mOxie.FileReader process and the AJAX request in RSVP promises so that chaining and utility methods such as .catch() always work as expected.

Demo

I’ve set up a quick demo so that you can see it in action.

This is just a starting point, of course. You can add all sorts of usability enhancements, such as progress bars, image previews etc. Happy hacking!