In this tutorial, I will teach you how to upload files with a progress bar using HTML5, CSS3, JavaScript, and PHP. The complete source code of this File Upload with Progress Bar project is given below.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>File Upload with Progress Bar</title> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"/> </head> <body> <div class="wrapper"> <header>File Uploader JavaScript</header> <form action="#"> <input class="file-input" type="file" name="file" hidden> <i class="fas fa-cloud-upload-alt"></i> <p>Browse File to Upload</p> </form> <section class="progress-area"></section> <section class="uploaded-area"></section> </div> <script src="script.js"></script> </body> </html>
const form = document.querySelector("form"), fileInput = document.querySelector(".file-input"), progressArea = document.querySelector(".progress-area"), uploadedArea = document.querySelector(".uploaded-area"); // form click event form.addEventListener("click", () =>{ fileInput.click(); }); fileInput.onchange = ({target})=>{ let file = target.files[0]; //getting file [0] this means if user has selected multiple files then get first one only if(file){ let fileName = file.name; //getting file name if(fileName.length >= 12){ //if file name length is greater than 12 then split it and add ... let splitName = fileName.split('.'); fileName = splitName[0].substring(0, 13) + "... ." + splitName[1]; } uploadFile(fileName); //calling uploadFile with passing file name as an argument } } // file upload function function uploadFile(name){ let xhr = new XMLHttpRequest(); //creating new xhr object (AJAX) xhr.open("POST", "php/upload.php"); //sending post request to the specified URL xhr.upload.addEventListener("progress", ({loaded, total}) =>{ //file uploading progress event let fileLoaded = Math.floor((loaded / total) * 100); //getting percentage of loaded file size let fileTotal = Math.floor(total / 1000); //gettting total file size in KB from bytes let fileSize; // if file size is less than 1024 then add only KB else convert this KB into MB (fileTotal < 1024) ? fileSize = fileTotal + " KB" : fileSize = (loaded / (1024*1024)).toFixed(2) + " MB"; let progressHTML = `<li class="row"> <i class="fas fa-file-alt"></i> <div class="content"> <div class="details"> <span class="name">${name} • Uploading</span> <span class="percent">${fileLoaded}%</span> </div> <div class="progress-bar"> <div class="progress" style="width: ${fileLoaded}%"></div> </div> </div> </li>`; // uploadedArea.innerHTML = ""; //uncomment this line if you don't want to show upload history uploadedArea.classList.add("onprogress"); progressArea.innerHTML = progressHTML; if(loaded == total){ progressArea.innerHTML = ""; let uploadedHTML = `<li class="row"> <div class="content upload"> <i class="fas fa-file-alt"></i> <div class="details"> <span class="name">${name} • Uploaded</span> <span class="size">${fileSize}</span> </div> </div> <i class="fas fa-check"></i> </li>`; uploadedArea.classList.remove("onprogress"); // uploadedArea.innerHTML = uploadedHTML; //uncomment this line if you don't want to show upload history uploadedArea.insertAdjacentHTML("afterbegin", uploadedHTML); //remove this line if you don't want to show upload history } }); let data = new FormData(form); //FormData is an object to easily send form data xhr.send(data); //sending form data }
/* Import Google font - Poppins */@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@400;500;600&display=swap'); *{ margin: 0; padding: 0; box-sizing: border-box; font-family: "Poppins", sans-serif; } body{ display: flex; align-items: center; justify-content: center; min-height: 100vh; background: #6990F2; } ::selection{ color: #fff; background: #6990F2; } .wrapper{ width: 430px; background: #fff; border-radius: 5px; padding: 30px; box-shadow: 7px 7px 12px rgba(0,0,0,0.05); } .wrapper header{ color: #6990F2; font-size: 27px; font-weight: 600; text-align: center; } .wrapper form{ height: 167px; display: flex; cursor: pointer; margin: 30px 0; align-items: center; justify-content: center; flex-direction: column; border-radius: 5px; border: 2px dashed #6990F2; } form :where(i, p){ color: #6990F2; } form i{ font-size: 50px; } form p{ margin-top: 15px; font-size: 16px; } section .row{ margin-bottom: 10px; background: #E9F0FF; list-style: none; padding: 15px 20px; border-radius: 5px; display: flex; align-items: center; justify-content: space-between; } section .row i{ color: #6990F2; font-size: 30px; } section .details span{ font-size: 14px; } .progress-area .row .content{ width: 100%; margin-left: 15px; } .progress-area .details{ display: flex; align-items: center; margin-bottom: 7px; justify-content: space-between; } .progress-area .content .progress-bar{ height: 6px; width: 100%; margin-bottom: 4px; background: #fff; border-radius: 30px; } .content .progress-bar .progress{ height: 100%; width: 0%; background: #6990F2; border-radius: inherit; } .uploaded-area{ max-height: 232px; overflow-y: scroll; } .uploaded-area.onprogress{ max-height: 150px; } .uploaded-area::-webkit-scrollbar{ width: 0px; } .uploaded-area .row .content{ display: flex; align-items: center; } .uploaded-area .row .details{ display: flex; margin-left: 15px; flex-direction: column; } .uploaded-area .row .details .size{ color: #404040; font-size: 11px; } .uploaded-area i.fa-check{ font-size: 16px; }
<?php $file_name = $_FILES['file']['name']; //getting file name $tmp_name = $_FILES['file']['tmp_name']; //getting temp_name of file $file_up_name = time().$file_name; //making file name dynamic by adding time before file name move_uploaded_file($tmp_name, "files/".$file_up_name); //moving file to the specified folder with dynamic name ?>
Now you need to create a folder called files
inside the php
folder. Basically, this folder will hold all the uploaded files.
We evaluated the performance of Llama 3.1 vs GPT-4 models on over 150 benchmark datasets…
The manufacturing industry is undergoing a significant transformation with the advent of Industrial IoT Solutions.…
If you're reading this, you must have heard the buzz about ChatGPT and its incredible…
How to Use ChatGPT in Cybersecurity If you're a cybersecurity geek, you've probably heard about…
Introduction In the dynamic world of cryptocurrencies, staying informed about the latest market trends is…
The Events Calendar Widgets for Elementor has become easiest solution for managing events on WordPress…