How to Upload and Display Multiple Images with JavaScript

Need to learn how to upload and preview multiple images? You have come to the right place. In this tutorial, I’ll break down all of the steps needed to do this easily and efficiently. Before we begin, however, I want to be clear that we will only upload the images on the front-end. Meaning that we won’t actually be uploading these images onto a database or AWS. If you want to be a full stack developer, then at some point you’ll want to learn that as well but for now you’ll want to start by learning how to simply upload and preview the images. By the way, I will keep things very simple for the sake of keeping this tutorial beginner friendly. Let’s get started.

In the HTML file, we’ll need:

<label for="files">Select multiple files</label>
<input id="files" type="file" multiple="multiple" accept="image/jpeg, image/png, image/jpg">
<output id="result">

Nothing special. A label, input, and output element. Notice the input has an attribute of multiple, this is needed in order to upload multiple files. We also included an attribute of accept that will only allow the user to upload images of type jpeg, png, or jpg. The purpose of the output element is to act as a container that will hold the images, which we will add later dynamically with JavaScript.

In the CSS file:

#result{
display: flex;
gap: 10px;
padding: 10px 0;
}
.thumbnail {
height: 200px;
}

Let’s add selectors to result and thumbnail. For this tutorial, the images will display in a row, so I added flexbox properties to the result container. This is optional of course, if you want the images to display differently then go ahead and add or delete properties. You might be wondering where the thumbnail class came from. We have not actually created this class in our HTML file yet, we will be doing so dynamically with JavaScript. For now, we are simply setting the properties we want it to have.

Alright, we have gotten to the JavaScript portion of the code, so to help you understand this better, I will break things down piece by piece.

We are going to start this off by adding a change event to the input field. This is going to detect whenever the user upload images. Please keep in mind that we will continue to add code inside this event as we move forward.

document.querySelector("#files").addEventListener("change", (e) => { });

Alright, now let’s check if the users browser supports the File API, which is what we’ll use to “read” the files the user uploads. A simple if else statement should be sufficient to get this done. Notice we included a courtesy message in the else statement that alerts the user about their browser not supporting the File API.

document.querySelector("#files").addEventListener("change", (e) => { 
if (window.File && window.FileReader && window.FileList && window.Blob) {
// CODE TO PREVIEW IMAGE
} else {
alert("Your browser does not support File API");
}
});

Now that we know the users browser supports the File API, let’s grab the images the user uploaded and store them in a variable named files. We also need to access the result container we created in the HTML file here. Every time the user uploads new images, we will delete the old images from the screen by setting the inner HTML of the output container to an empty string. You can of course design this differently in the future but let’s do it this way for now.

document.querySelector("#files").addEventListener("change", (e) => { 
if (window.File && window.FileReader && window.FileList && window.Blob) {
const files = e.target.files;
const output = document.querySelector("#result");
output.innerHTML = ""; }
else {
alert("Your browser does not support File API");
}
});

Now let’s create a for loop that iterates through each of the user uploaded images. If any of the user uploaded files doesn’t contain the word “image”, we know the user didn’t upload a permitted file type. To catch this error, we will use the keyword continue. This keyword will stop the for loop in it’s tracks and move on to the next index.

document.querySelector("#files").addEventListener("change", (e) => { 
if (window.File && window.FileReader && window.FileList && window.Blob) {
const files = e.target.files;
const output = document.querySelector("#result");
output.innerHTML = "";
for (let i = 0; i < files.length; i++) {
if (!files[i].type.match("image")) continue;
}
} else {
alert("Your browser does not support File API");
}
});

At this point, we need to read the user uploaded file with FileReader object and add a change event so we can display the image. In order to display the image, we need to create an element of type img and set the src to the data URI we got from the FileReader object. Notice that we also gave the img element a class name of thumbnail. This is the same class we created a selector for in the CSS file!

Here is the final version of the change event:

document.querySelector("#files").addEventListener("change", (e) => { 
if (window.File && window.FileReader && window.FileList && window.Blob) {
const files = e.target.files;
const output = document.querySelector("#result");
output.innerHTML = "";
for (let i = 0; i < files.length; i++) {
if (!files[i].type.match("image")) continue;
const picReader = new FileReader();
picReader.addEventListener("load", function (event) {
const picFile = event.target;
const div = document.createElement("div");
div.innerHTML = `<img class="thumbnail" src="${picFile.result}" title="${picFile.name}"/>`;
output.appendChild(div);
});
picReader.readAsDataURL(files[i]);
}
} else {
alert("Your browser does not support File API");
}
});

You’re welcome!

Can’t get it to work? Check out my codepen and/or a more in depth tutorial video below.

--

--

--

Passionate software developer with an eye for design and detail. Contact me: https://miguelznunez.com/

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Introduction to Webpack

Laravel Unique Validation Rules Examples

Neumorphism Social Button Icons

Setting Up a NodeJS React Environment: The SUPER Easy Way

Neo4j PageRank Algorithm and Path Pattern Matching on Flights Domain Model

Survival Guide on Javascript (for the Elm Developer)

Danny xtrim teams up with Bayologic beatz to work on a new song ‘POVERTY BYE’, listen!!;

Things to watch-out while implementing Live Location Sharing in React Native

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Miguel Nunez

Miguel Nunez

Passionate software developer with an eye for design and detail. Contact me: https://miguelznunez.com/

More from Medium

How to Count the Number of Visits on your Website with HTML, CSS, JavaScript and the Count API

Template Literals in JavaScript ES6

#4 Building a JavaScript & HTML Browser RPG: Novel Movements

JavaScript Coding Tutorial — Part 11 — Green Jelly Beans!

Nice little final touch with an offset drop shadow, like we learned previously.