Monday, November 30, 2020

Uploading Files With AJAX

I can’t seem to reach the end of the fun stuff you can do with web technologies. Today, I’m going to show you how to upload files via AJAX.

First, we'll see how to upload files using vanilla JavaScript. And later on, I'll show how you could use the DropzoneJS library to implement drag-and-drop file uploads.

Looking for a Quick Solution?

If you're looking for a quick solution, there's a great collection of file upload scripts and applications over at CodeCanyon.

JavaScript File Loaders and Uploaders

How to Upload a File With Vanilla JavaScript

There are three main components to our project.

  • The multiple attribute on the file input element.
  • The FileReader object from the new File API.
  • The FormData object from XMLHttpRequest.

We use the multiple attribute to allow the user to select multiple files for upload (multiple file upload will work normally even if FormData isn’t available). As you’ll see, FileReader allows us to show the user thumbnails of the files they’re uploading (we’ll be expecting images).

For older browsers that don't support FormData or FileReader, the upload behavior will fall back to a normal, non-AJAX file upload.

With that out of the way, let’s get coding!

Step 1: The Markup and Styling

Let’s start with some basic markup and styling. Of course, this isn’t the main part of this tutorial, I won’t treat you like a newbie.

The HTML

Pretty basic, eh? We’ve got a form that posts to upload.php, which we’ll look at in a second, and a single input element, of type file. Notice that it has the boolean multiple attribute, which allows the user to select multiple files at once.

That’s really all there is to see here. Let’s move on.

The CSS

No shockers here, we're just creating some basic styling for our upload form.

Step 2: The PHP

We need to be able to handle the file uploads on the back end as well, so let’s cover that next.

upload.php

Bear in mind that these were the first lines of PHP I’d written in easily a year. You should probably be doing a bit more for security; however, we’re simply making sure that there are no upload errors. If that’s the case, we use the built-in move_uploaded_file to move it to an uploads folder. Don’t forget to make sure that the folder is writable.

So, right now, we should have a working upload form. You choose an image (multiple, if you want to and your browser lets you), click the Upload Files! button, and you get the message Successfully Uploaded Images.

Here’s what our mini-project looks like so far:

But, come on, it’s 2020: we want more than that. You’ll notice that we’ve linked up jQuery and an upload.js file. Let’s crack that open now.

Step 3: The JavaScript

Let’s dive right into the JavaScript code for file uploading!

Here’s what we start with. We create two variables: input is our file input element, formdata will be used to send the images to the server if the browser supports that. We initialize it to false and then check to see if the browser supports FormData. If it does, we create a new FormData object. Also, if we can submit the images with AJAX, we don’t need the Upload Images! button, so we can hide it. Why don’t we need it? Well, we’re going to auto-magically upload the images immediately after the user selects them.

The rest of the JavaScript will go inside your anonymous self-invoking function. We next create a little helper function that will show the images once the browser has them:

The function takes one parameter: the image source (we’ll see how we get that soon). Then, we simply find the list in our markup and create a list item and image. We set the image source to the source we received, put the image in the list item, and put the list item in the list. Voila!

Next, we have to actually take the images, display them, and upload them. As we’ve said, we’ll do this when the onchange event is fired on the input element.

So, what do we want to do when the user has selected files? First, we create a few variables. The only important one right now is len = this.files.length. The files that the user has selected will be accessible from the object this.files. Right now, we’re only concerned with the length property, so we can loop over the files... and that is exactly what we’re doing next. Inside our loop, we set the current file to file for ease of access. Next thing we do is confirm that the file is an image. We can do this by comparing the type property with a regular expression. We’re looking for a type that starts with “image” and is followed by anything. (The double-bang in front just converts the result to a boolean.)

So, what do we do if we have an image on our hands?

We check to see if the browser supports creating FileReader objects. If it does, we’ll create one.

Here’s how we use a FileReader object: We’re going to pass our file object to the reader.readAsDataURL method. This creates a data URL for the uploaded image. It doesn’t work the way you might expect, though. The data url isn’t passed back from the function. Instead, the data url will be part of an event object.

With that in mind, we'll need to register a function on the reader.onloadend event. This function takes an event object, by which we get the data URL: it’s at e.target.result. We’re just going to pass this data RUL to our showUploadedItem function (which we wrote above).

Next, we check for the formdata object. Remember, if the browser supports FormDataformdata will be a FormData object; otherwise, it will be false. So, if we have a FormData object, we’re going to call the append method. The purpose of a FormData object is to hold values that you’re submitting via a form; so, the append method simply takes a key and a value. In our case, our key is images[]. By adding the square-brackets to the end, we make sure each time we append another value, we’re actually appending it to that array, instead of overwriting the image property.

We’re almost done. In our for loop, we’ve displayed each of the images for the user and added them to the formdata object. Now, we just need to upload the images. Outside the for loop, here’s the last piece of our puzzle:

Again, we have to make sure we have FormData support; if we don’t, the Upload Files! button will be visible, and that’s how the user will upload the photos. However, if we have FormData support, we’ll take care of uploading via AJAX. We’re using jQuery to handle all the oddities of AJAX across browsers.

You’re probably familiar with jQuery’s $.ajax method: you pass it an options object. The urltype, and success properties should be obvious. The data property is our formdata object. Notice those processData and contentType properties. According to jQuery’s documentation, processData is true by default, and will process and transform the data into a query string. We don’t want to do that, so we set this to false. We’re also setting contentType to false to make sure that data gets to the server as we expect it to.

And that’s it. Now, when the user loads the page, they see this:

And after they select the images, they’ll see this:

And the images have been uploaded:

So that's how you can upload files using the vanilla JavaScript. In the next section, we'll see how to implement file upload with the DropzoneJS library.

How to Use the DropzoneJS Library

The DropzoneJS library is a popular free library which allows you to implement the file uploads functionality the blink of an eye. It also supports drag-and-drop file uploads along with a beautiful preview feature.

Let's have a look at the following code which implements the file upload functionality with DropzoneJS.

You'll have to download the dropzone.js and dropzone.css files locally first.

Apart from that, you just need to use the dropzone class in the form tag, and the DropzoneJS library will handle the rest!

Let's see how it looks like when you load it in your browser.

As you can see, there's a section which allows you to drop files on it, alternatively you could also select files from your computer by using the default file selection dialog box. Go ahead and drop a few image files on it and it should present you a nice preview as shown in the following screenshot.

Isn't that look amazing with just a few lines of code? In fact, the DropzoneJS library also allows you to customize the UI and other stuff. I would encourage you to check the configuration options provided by this library.

Apart from this, there's the filepond library which is also a popular file upload library you could use. It provides all niche features like drag and drop, progress bar, previews, reordering and alike.

That’s a Wrap!

Uploading files via AJAX is pretty cool, and it’s great that these new technologies support that without the need for lengthy hacks.

Learn JavaScript With a Free Course

If you want to master JavaScript, be sure to check out our free course to learn the complete A-Z of modern JavaScript fundamentals.

 

In this course, you'll learn all of the essential concepts of the JavaScript language. That's right: all of them! Including the most important recent improvements to the language, in JavaScript ES6 (ECMAScript 2015) and JavaScript ES7 (ECMAScript 2016).

You'll start with the very fundamentals of the language: variables and datatypes. Then in each lesson you'll build knowledge, from data structures like arrays and maps to loops, control structures, and functions. Along with the basics of the language, you'll also learn some key built-in APIs for manipulating data, AJAX, and working with the web browser DOM. Finally, you'll get a look at some of the most powerful and widely used web APIs that are supported by all modern browsers.

This post has been updated with contributions from Sajal Soni. Sajal belongs to India and he loves to spend time creating websites based on open source frameworks.

No comments:

Post a Comment