November 05, 2018
Ajax File Upload with Dynamic Progress Bar
ajax javascript jquery
I tried to make an ajax file upload which will handle multiple file uploads with dynamic progress bars just like uploadify.js. Lets see what I achieved so far and how we can handle ajax file uploads.
Ok, Files we are going to need are index.php which will contain the form code, style.css will contain the styles of page, javascript.js will be holding the code to handle ajax file upload and process-upload.php will process the upload on server side.
index.php
<!DOCTYPE html> <html> <head> <title>Ajax File Upload with Dynamic Progress Bar Demo</title> <meta content="text/html; charset=UTF-8" http-equiv="Content-Type"/> <script type="text/javascript" src="js/jquery-3.1.1.min.js"></script> <script type="text/javascript" src="js/javascript.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"/> <link rel="stylesheet" href="css/style.css" /> </head> <body> <div class="main-container"> <div class="section"> <form id="ajax-upload-form" enctype="multipart/form-data"> <div class="row"> <div class="col-10"> <input type="file" class="file-input" name="ajax_file" multiple="multiple"/> </div> <div class="col-2 text-right"> <button type="submit" class="btn btn-blue"><i class="fa fa-upload"></i> Upload</button> </div> </div> </form> <div class="progress-container"></div> </div> </div> </body> </html>
javascript.js
$(document).ready(function () { $("#ajax-upload-form").submit(function (e) { e.preventDefault();// Prevent form from being submitted. var fd = new FormData();// Create new form data object to push files into var files = $(".file-input")[0].files;// Getting all files from input field //Loop through all files and append progress bar for each file for (var i = 0; i < files.length; i++) { fd.append("ajax_file", files[i]); var regEx = /^(image|video|audio)\//; //Creating the progress bar element var bar = '<div class="progress" id="' + i + '">' + '<span class="abort" id="abort-' + i + '">×</span>' + '<div class="progress-title" id="progress-title-' + i + '"></div>' + '<div class="progress-bar" id="progress-bar-' + i + '"></div>' + '</div>'; $(".progress-container").append(bar);// Append progress bar to container //If file is not image,audio or upload through add error class to progress otherwise process upload if (files[i].type.match(regEx)) { //Function to upload single file uploadFile(fd, i, files[i]); } else { $("#progress-bar-" + i).closest(".progress") .addClass("progress-error"); $("#progress-title-" + i).text("Invalid file format"); } // If all files have been uploaded rest the form if (i === (files.length - 1)) this.reset(); } }); // Remove progress bar with error class $(document).on("click", ".progress-error > .abort", function () { $(this).closest(".progress").fadeOut(3000, function () { $(this).remove(); }); }); }); function uploadFile(fd, i, file) { var ajax = $.ajax({ url: 'process-upload.php',// Server side script to process uploads type: 'POST', data: fd, processData: false,//Bypass jquery's form data processing contentType: false,//Bypass jquery's content type to handle file upload xhr: function () { var xhr = $.ajaxSettings.xhr(); if (xhr.upload) { //Listen to upload progress and update progress bar xhr.upload.addEventListener("progress", function (progress) { var total = Math.round((progress.loaded / progress.total) * 100); $("#progress-bar-" + i).css({"width": total + "%"}); $("#progress-title-" + i).text(file.name + ' - ' + total + "%"); }, false); //Code to be executed if upload is aborted xhr.addEventListener("abort", function () { $("#progress-bar-" + i).closest(".progress").fadeOut(3000, function () { $(this).remove(); }); }, false); //Update progress and remove it after upload has finished xhr.addEventListener("loadend", function () { $("#progress-bar-" + i).closest(".progress").fadeOut(3000, function () { $(this).remove(); }); }, false); //Show an error on progress if an error has occured during upload xhr.addEventListener("error", function () { $("#progress-bar-" + i).closest(".progress") .addClass("progress-error").find("status-count").text("Error"); }, false); //Show timeout error on progress bar if upload request has timedout xhr.addEventListener("timeout", function (progress) { $("#progress-bar-" + i).closest(".progress") .addClass("progress-timedout").find("status-count").text("Timed Out"); }, false); } return xhr; } }); // Bind abort to current ajax request. $(document).on("click", ".progress > #abort-" + i, function () { ajax.abort(); }); }
style.css
*{ box-sizing: border-box; } html,body{ margin: 0px; padding: 0px; } body{ background: #f0f0f0; font: normal normal 14px Open Sans,Verdana, Arial; } .main-container{ max-width: 1024px; margin: 0px auto; } .section { padding: 15px; } .text-right{ text-align: right; } .row:before, .row:after{ content: ' '; display: table; } .row:after{ clear:both; } .row{ margin-left: -10px; margin-right: -10px; margin-bottom: 10px; } [class*="col-"] { float: left; padding: 0px 10px; } .col-2{ width: 16.66%; } .col-10{ width: 83.33%; } .btn{ display: inline-block; padding: 5px 10px; cursor: pointer; } .btn-blue{ background: #3c8dbc; border: 1px solid #2b7cab; color: #fff; } .progress{ background: #fff; border: 1px solid #00a65a; margin-bottom: 10px; padding: 5px; } .progress > .abort{ float: right; font-size: 20px; cursor: pointer; line-height: 18px; opacity: 0.5; } .progress > .abort:hover{ opacity: 1; } .progress-error{ border: 1px solid #e65442; color: #e65442; } .progress > .progress-bar{ width: 0%; transition: width ease .1s; background-color: #00a65a; max-width: 100%; height: 5px; margin-top: 5px; } .progress-error > .progress-bar{ background-color: #e65442; }
process-upload.php
<?php // Code to process uploads if($_FILES && !$_FILES['ajax_file']['error']){ $allowed_types = ["audio","image","video"]; $type = substr($_FILES['ajax_file']['type'],0,5); //Check if uploaded file is image,audio or video then save file if(in_array($type,$allowed_types)){ move_uploaded_file($_FILES['ajax_file']['tmp_name'],"uploaded-files/".$_FILES['ajax_file']['name']); } } ?>