Series: Drag-n-Drop Image Uploads

Image Upload Preview

Published on Jun 21, 2015

When you're uploading an image, you want the immediate feedback of seeing the image you've selected.

This screencast shows how to display the image to the user after they've selected it but before they've committed to uploading it to the server.


Links

Code

previewImage: Ember.observer('file', function(){
  var file = document.getElementById('file-field').files[0];
  if (file) {
    var reader = new FileReader();

    reader.onload = function (e) {
      $('#preview-image').attr('src', e.target.result);
    }

    reader.readAsDataURL(file);
  }
})

Transcript

Today, we’re going to take our image upload and add a preview functionality to it. The way we go about this is a little bit un-Embery, and I’ll argue that this is okay, since the un—Embery parts are kept wrapped up in a component where the rest of the program will never see them or interact with them.

The basic architecture of this will be to watch the file in the file field, and when the file changes, we’ll change the image preview. We’ll start by setting up an image tag that displays by default the currently saved image. We’ll copy it from the show template and paste it into the edit fields template. This will show the image on the edit and new pages.

Then we’ll turn the input into an Ember input, allowing us to give it a value binding. In the component, we’ll set up an observer so we can watch when the value changes.

You may have heard lately about how bad observers are for performance. That is true when there are many interconnected observers. The more observers and the wider the swath of things that they’re watching, the worse performance gets.

However, this is one observer watching one thing that only changes with direct input of the user. It doesn’t interact with the rest of the program. Therefore, it won’t trigger the performance killing loops that Stephan Penner, and other core team members have warned about.

So when the file binding changes, we try to grab the file. If we were able to grab the file, we use the fileReader API. We set up an onload hook, which grabs the local file url and stuffs it into the source attribute of the previewImage. Then we use the readAsDataURL method. This triggers the onload hook that we set up earlier, handing it an object that contains the file url.

So to review this code, we create a new file reader, then we set up the onload hook, then we use the readAsDataURL method which triggers the onload hook, which then reads the file url and puts it into the previewImage source attribute. To make this work, we’ll add the idea of previewImage to our image.

Let’s test out this preview code. We’ll choose a new screenshot and see that we’re previewing it correctly, and that it will still save.

This is a little bit un-Embery, a little bit spaghetti-ish, but that’s okay to do if you isolate the spaghetti from the rest of your Ember app. If you stuff the spaghetti inside a Ziploc bag, it won’t make much of a mess. In this case, the trickery never makes it outside the component.

I hope this tidbit has helped you in your quest for nice user-friendly forms. Until next time, keep being awesome.

Drag-n-Drop Image Uploads

Subscribe to our mailing list