Preview and validate an image with JavaScript

Updated: 07-Jan-2022 / Tags: HTML, CSS and Javascript / Views: 2219 - Author: George

Introduction

When we ask our users on our website to upload an image, it's good practice and a positive user experience to display a preview of the selected image, alongside basic validation.

So in this post we are going to see how to instant preview and validate an image, using the fileReader object in JavaScript.

Live demo

Try out the live demo.
If you choose images larger than 2MB you will see an error, or if you select files that are not images like .txt files, or they don't have a .png .jpg or .gif extension you will see an error. Else you will see a preview of the selected image and its properties (size, name, and type).

Project files

We need two files.

  • An index.html file, where we will write our form.
  • A script.js file, where we are going to write the javascript code.

The index file

In the index.html file we have our form element.

<form action="" method="post" enctype="multipart/form-data">
	<p class="preview">
		<img id="image" src="" alt="">
		<span>Image Preview</span>
	</p>

	<p class="file-info"></p>
	<p id="error"></p>
	<input type="file" onchange="imagePreview(this)">
</form>

<script src="script.js"></script>

HTML code breakdown

Lets take a look at the form element and it's attributes.

<form action="" method="post" enctype="multipart/form-data">
  • action=""... the action attribute sends the form data to the file we specify. Here the action attribute is empty, that means that the form will submit the data to the same page.
  • method="post"... the http request method is set to post.
  • enctype="multipart/form-data"... when we dealing with files, the enctype must be set to multipart/form-data, else the upload process will not work.
  • Actually in this tutorial we don't need any of these attributes, because we are only previewing the image file, but if you are going to take this code and extend it to upload an image, you are gonna need those attributes.

The first element inside the form is a p tag with a class="preview" this is our selected image's placeholder.
Inside we have an img tag with an id="image" and an empty src="" tag. We are going to fill the empty src tag with the selected image's source data using javascript.

<p class="preview">
	<img id="image" src="" alt="">
	<span>Image Preview</span>
</p>

In line 7 we have a placeholder where we displaying the details about the selected image.

<p class="file-info"></p>

In line 8 we have an error placeholder where we are showing any error from the validation process. We are going to use the id="error" to target the element from the javascript file.

<p id="error"></p>

In line 9 we have the choose file button, so we can choose a file from our computer.

<input type="file" onchange="imagePreview(this)">
  • onchange="imagePreview(this)"... there is an onchange event-listener attached to the input element, that means that every time we choose an image from our hard drive, the imagePreview(this) function will run.
  • The argument (this) will give us access to the selected image.

And in line 12 we are linking the javascript file with the index page.

<script src="script.js"></script>

The javascript code script.js

function imagePreview(input){
	let error = document.querySelector("#error");
	error.innerHTML = "";
	document.querySelector(".file-info").innerHTML = "";

	if(input.files){
		let file = input.files[0];
		let reader = new FileReader();

		reader.readAsDataURL(file);
		reader.onload = function(){
			if(reader.readyState == 2){
				document.getElementById("image").src = reader.result;
			}
		}

		if(file.size > 1024 * 1024 * 2){
			error.innerHTML = "File must be smaller than 2MB";
			return false;
		}

		let allowedImageTypes = ["image/jpeg", "image/gif", "image/png"];
		if(!allowedImageTypes.includes(file.type)){
			error.innerHTML = "Allowed file type's are: [ .jpg .png .gif ]";
			return false;
		}

		let fileInfo = `
			<ul>
				<li> File name: <span>${file.name}</span> </li>
				<li> File size: <span>${file.size} bytes</span>  </li>
				<li> File type: <span>${file.type}</span> </li>
			</ul>
		`;
		document.querySelector('.file-info').innerHTML = fileInfo;
	}
}

Javascript code breakdown

We start the code in the javascript file by declaring the image preview function. The (input) argument will give us access to the choose file button and the selected image.

function imagePreview(input)

In line 2-3 we are targeting the error element and initialize it to an empty string. That means that every time the function runs we clear any previous error.

let error = document.querySelector("#error");
error.innerHTML = "";

We are doing the same thing with the .file-info element in line 4

document.querySelector(".file-info").innerHTML = "";

Next in line 6 to 15 we are going to check if there is a selected file. If so we are going to read that file with the FileReader object, and the result of that reading will be added in our image's placeholder's src attribute.
And so we are having our preview of the selected image.

if(input.files){
	let file = input.files[0];
	let reader = new FileReader();

    reader.readAsDataURL(file);
    reader.onload = function(){
		if(reader.readyState == 2){
			document.getElementById("image").src = reader.result;
		}
	}	
}
  • In line 6 we are checking the input.files to see if there is a file selected. The .files is a method of the input object and holds an array, of the selected images. In our case we selecting only one image so this image is stored in index [0].
  • In line 7 we targeting the selected image, and we store it in the file variable. Now the file variable holds the images details such as, name, type, and size
  • In line 8 we creating a variable with name reader and store a FileReader object. Now we can use the reader variable to access the methods of the FileReader object.
  • In line 10 we use the readAsDataUrl method and we pass as an argument the selected file. The readAsDataUrl method reads the raw image data.
  • Next we have to check if the reading is completed. We do this with the .onload property in line 11. If the reading is completed we check the .readyState property which will have the value 2.
  • Then we are targeting the img src="" attribute inside the preview placeholder and we adding the image's data that the reader.result holds.
    That's it we have our preview.

Next in line 17 to 20 we are going to validate the file size.
If the size of the file is bigger than 2MB, we displaying an error message and stopping the function with the return false statement.

if(file.size > 1024 * 1024 * 2){
    error.innerHTML = "File must be smaller than 2MB";
    return false;
}

From line 22 to 26 we are going to check if the selected file is one of the valid types ( .jpg .png .gif ).

let allowedImageTypes = ["image/jpeg", "image/gif", "image/png"];
	if(!allowedImageTypes.includes(file.type)){
	   error.innerHTML = "Allowed file type's are: [ .jpg .png .gif ]";
	   return false;
}
  • In line 22 we have an array of valid image types.
  • .includes(file.type)... with the includes() method we are checking if the selected (file.type) exists in the array. with the ! exclamation point we say NOT.
    So in human language we are saying. If the incoming file type is NOT in the array, display an error message and stop the function.

And in our last code-block we display the name, the size, and the file type of the selected image in the file-info element.

<p class="file-info"></p>

We are using here a template literal. To do so we use the back ticks (``) and write standard html between them.
To display variables inside a template literal we use the dollar sign and curly braces ${}.

let fileInfo = `
    <ul>
       <li> File name: <span>${file.name}</span> </li>
       <li> File size: <span>${file.size} bytes</span>  </li>
       <li> File type: <span>${file.type}</span> </li>
    </ul>
`;
document.querySelector('.file-info').innerHTML = fileInfo;

The last we have to do is to target the file-info p tag and displaying the fileInfo variable in 35.

let file = input.files[0];

Summary

We saw how to read a file with the FileReader() object. How to check the files size and type, and how to access the file's properties and display them in a template literal.

I hope that everything made sense.
Thanks for reading.

If you want to know how to preview and upload multiple files at once check this post out:
Preview and upload multiple files with javascript (AJAX) and PHP

Source code

You can download the source code and use it in any way you like.

Times downloaded: 89

Buy me a coffee

If you like to say thanks, you can buy me a coffee.

Buy me a coffee with paypal

Comment section

You can leave a comment, it will help me a lot.

Or you can just say hi. 😉