3 Steps Simple AJAX Upload With Progress Bar (Pure Javascript)

INTRODUCTION

LET THERE BE UPLOAD PROGRESS

Welcome to a tutorial on how to create a simple AJAX upload with a progress bar – Using only pure Javascript and CSS. Once upon a time in the Dark Ages of the Internet, we have to use all sorts of third-party libraries to track the upload progress. Those days are gone and we can actually track uploads using only pure Javascript – Read on to find out how!

ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

 

PREAMBLE

DOWNLOAD & NOTES

First, here is the download link to the example source code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

  • Download and unzip into your project folder.
  • Scripts are “not working”?
    • Open the developer’s console (F12 in most major browsers), check the error message.
    • Captain Obvious to the rescue, AJAX calls will only work with http://, not file://.

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

ENABLE UPLOADS

On your web server, please ensure that file uploads are enabled in the php.ini file. This is a silly mistake that some beginners actually miss out and wonder why their uploads always fail.

php.ini
file_uploads = On

Next, you might also want to change the allowed maximum file size.

php.ini
upload_max_filesize = 10M
post_max_size = 10M

 

 

STEP 1

HTML & CSS

All right, let us now start by creating a very simple HTML file upload form and upload progress bar.

 

HTML UPLOAD FORM & PROGRESS BAR

1-upload.html
<style>
/* [PROGRESS BAR] */
#progress, #bar {
  height: 30px;
}
#progress {
  width: 300px;
  border: 1px solid #000;
}
#bar {
  width: 1px;
  background: #4286f4;
  transition: width ease 0.3s;
}
</style>
 
<!-- [PROGRESS BAR] -->
<div id="progress">
  <div id="bar"></div>
</div>
<br><br>

<!-- [UPLOAD FORM] -->
<form id="upform" onsubmit="return save()">
  <input type="file" id="upfile" required/>
  <br><br>
  <input type="submit" value="START!" id="upstart"/>
</form>

Yep, that is actually all we need for the HTML and CSS. Just a “regular Joe” file upload <form> and progress bar <div id="progress">. Do feel free to tweak this to fit your own project needs – Add more fields, or just let it be a pure file upload only.

The CSS cosmetics are just about as simple – <div id="progress"> is pretty much the “outside border” of the progress bar, and we adjust the width of <div id="bar"> to display the upload progress.

 

 

STEP 2

JAVASCRIPT

Next, we move on to the next piece of the action, Javascript to run a file upload AJAX request.

 

JAVASCRIPT AJAX UPLOADER

2-upload.js
function save() {
  /* (A) FILE UPLOAD */
  var data = new FormData(),
  upfile = document.getElementById("upfile").files;
  data.append("upfile", upfile[0]);
 
  /* (B) AJAX */
  var xhr = new XMLHttpRequest();
  xhr.open("POST", "3-upload.php");
 
  /* (C) PROGRESS BAR */
  var percent = 0,
  maxwidth = 300,
  width = 0,
  bar = document.getElementById("bar"),
  start = document.getElementById("upstart");
 
  xhr.upload.onloadstart = function (evt) {
    percent = 0;
    bar.style.width = "1px";
    start.disabled = true;
  };
 
  xhr.upload.onprogress = function (evt) {
    percent = evt.loaded / evt.total;
    width = Math.ceil(percent * maxwidth);
    bar.style.width = width + "px";
  };
 
  xhr.upload.onloadend = function (evt) {
    start.disabled = false;
  };
  xhr.onload = function (){
    console.log(this);
    console.log(this.response);
    console.log(this.status);
  };
 
  /* (D) GO! */
  xhr.send(data);
  return false;
}

Don’t be intimidated by the seemingly “difficult” Javascript here. Not going to explain line-by-line, but the essential sections are:

  • First, we create a var data = new FormData() object. Use it to get the selected upload file.
  • Next, create a new var xhr = new XMLHttpRequest() AJAX request.
  • The progress bar part is probably the most confusing, but in essence, this part is only calculating and updating the upload progress.
    • xhr.upload.onloadstart is fired when the upload first starts. We use this to reset the progress bar.
    • xhr.upload.onprogress is fired as the upload is ongoing. We use this to update the upload progress.
    • xhr.upload.onuploadend and xhr.onload is fired when the upload ends.

 

 

STEP 3

SERVER-SIDE SCRIPT

Now that we have dealt with the client-side form, the final step is to deal with the uploaded file itself.

 

PHP UPLOAD HANDLER

ajax-upload.php
<?php
// (A) MOVE UPLOADED FILE
$source = $_FILES["upfile"]["tmp_name"];
$destination = $_FILES["upfile"]["name"];
move_uploaded_file($source, $destination);

// (B) RESPONSE
echo "OK";

Er… Yep, this is kept as simple as possible. No checks, no gimmicks. Feel free to add your own stuff and processing here.

 

 

EXTRA

USEFUL BITS & LINKS

We have now finished with all the demo scripts, and here are a couple of extras that you may find useful.

 

COMPATIBILITY CHECKING & FALLBACK

Not the entire world is using the most updated browsers. If you want to support the older technology, you can add a few quick lines of Javascript to check if the Files API exists, then do the necessary fallback if required.

2-upload.js
if (window.File && window.FileList && window.FormData) {
  // All green - Proceed as usual
} else {
  // Fallback to use traditional upload without progress bar
}

 

LINKS & REFERENCES

 

INFOGRAPHIC

AJAX Upload WIth Progress Bar (click to enlarge)

 

CLOSING

WHAT NEXT?

Thank you for reading, and we have come to the end of this guide. I hope it has helped you with your project, and if you have anything to add to the guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “3 Steps Simple AJAX Upload With Progress Bar (Pure Javascript)”

  1. Hi!!

    Nice tutorial but if you get an error, e.g select a rar-file (validation error) you receive an error message but the progress bar still moves to 100% after the error message.

    Is it possible to display how meny procent that has been uploaded?

Leave a Comment

Your email address will not be published. Required fields are marked *