Multiple File Uploading with Progress Bar in HTML CSS and JavaScript

 

Hey Friend! Let's Build a Cool File Uploader

 

Uploading multiple files with a progress bar? Sounds cool, right?

 

we’re building exactly that! create a Multiple File Uploading system using HTML, CSS, JavaScript (jQuery), and PHP. You’ll be able to drag & drop files, see a progress bar, and even cancel or delete uploads if needed. Let’s do this step by step!

 

 

Multiple File Uploading with Progress Bar in HTML CSS and JavaScript

 

 


Features We’re Adding:


  • Drag & drop file upload
  • Real-time progress bar
  • Show file details (name, size, status)
  • Cancel or delete uploaded files
  • Server-side handling with PHP and MySQL

 

What You Need:

 

  • Basic knowledge of HTML, CSS, JavaScript, and PHP
  • A local server (XAMPP, WAMP, or MAMP)
  • A database (if you want to store uploads)

 

Step 1: Setting Up the HTML

 

Multiple File Uploading with Progress Bar in HTML CSS and JavaScript

 

 

Let’s start with the structure of our page. We need a drag & drop area and a list to show uploaded files.

 



<!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</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <link rel="stylesheet" href="style.css">
</head>
<body>
<div class="file-uploader">
	<div class="upload-container">
	<h6 class="pb-2 mb-0 title-txt">Multiple File Uploads</h6>	
	</div>
    <div class="ms-4 file-inr">
	   <p id="status-bar" class="status-bar py-3">Files Uploaded: 0 / Completed: 0</p>
        <div id="file-drop-area" class="file-container ms-4">
            <p>Click or Drag & Drop files here</p>
        </div>		
        <input type="file" id="file-input" multiple hidden>       
        <div id="file-list" class="file-list ms-4"></div>
    </div>  
</div>
<script src="script.js"></script>
</body>
</html>



Explanation:

 

The `file-container` is a drop area for dragging files.

 

`file-input` is hidden but triggered when the user clicks the container.

 

`file-list` displays uploaded files and progress.


Wow.! perfectly we create html file upload html code and Now ,we need to give a nice look for the html code with css.



Style.css




* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
body {
		  display: flex;
		  align-items: center;
		  padding: 15px;
		  justify-content: center;
		  min-height: 100vh;
		  background: #faf9fe;
}
		.file-uploader{
			 width: 500px;
			  background: #fff;
			  border-radius: 5px;
			  box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
			 
		}
		.file-inr{padding-bottom:3rem;}
		.file-uploader .upload-container {
			  
			  padding: 20px;
			  background: #EEF1FB;
			  align-items: center;
			  border-radius: 5px 5px 0 0;
			  justify-content: space-between;
			
		}
        .upload-container .title-txt{
			
              font-size: 1.2rem;
			  font-weight: 700;
			  text-transform: uppercase;
        }
		
        .file-container {
            width: 400px;
            border: 2px dashed #007bff;
            background-color: white;
            padding: 20px;
            text-align: center;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            border-radius: 10px;
            transition: 0.3s;
            cursor: pointer;
			
        }
        .file-container p {
            margin: 0;
            font-size: 18px;
            color: #333;
        }
        .file-container.drag-over {
            border-color: #28a745;
            background-color: #f1f8f4;
        }
        .file-list {
            margin-top: 20px;
            width: 400px;
        }
        .file-item {
            display: flex;
            align-items: center;
            background: white;
            padding: 10px;
            border-radius: 8px;
            box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.1);
            margin-bottom: 10px;
            position: relative;
        }
        .file-icon {
            width: 40px;
            height: 40px;
            background-color: #6c5ce7;
            color: white;
            font-weight: bold;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 8px;
            font-size: 14px;
            margin-right: 10px;
            text-transform: uppercase;
        }
        .file-info {
            flex-grow: 1;
        }
        .file-name {
            font-size: 14px;
            font-weight: bold;
            color: #333;
        }
        .file-size {
            font-size: 12px;
            color: #666;
        }
        .progress-container {
            width: 100%;
            height: 4px;
            background: #ddd;
            border-radius: 2px;
            margin-top: 5px;
            position: relative;
        }
        .progress-bar {
            height: 4px;
            background: #6c5ce7;
            width: 0%;
            border-radius: 2px;
        }
        .delete-btn, .cancel-btn {
            cursor: pointer;
            color: #333;
            font-weight: bold;
            margin-left: 10px;
        }
        .delete-btn {
            color: #333;
            cursor: pointer;
            display: none; /* Initially hidden */
        }
        .status-bar {
            margin-top: 15px;
            font-size: 16px;
            font-weight: bold;
            color: #333;
	    text-align:center;
        }



Step 2: JavaScript to Handle File Upload 

 

Now, let’s make this thing actually work! Copy and paste this into a script.js file.  

 



$(document).ready(function () {
    let fileDropArea = $("#file-drop-area");
    let fileInput = $("#file-input");
    let fileList = $("#file-list");
    let statusBar = $("#status-bar");

    let totalFiles = 0;
    let completedFiles = 0;

    fileDropArea.on("click", function () {
        fileInput.click();
    });

    fileInput.on("change", function (e) {
        let files = e.target.files;
        handleFiles(files);
    });

    fileDropArea.on("dragover", function (e) {
        e.preventDefault();
        fileDropArea.addClass("drag-over");
    });

    fileDropArea.on("dragleave", function () {
        fileDropArea.removeClass("drag-over");
    });

    fileDropArea.on("drop", function (e) {
        e.preventDefault();
        fileDropArea.removeClass("drag-over");
        let files = e.originalEvent.dataTransfer.files;
        handleFiles(files);
    });

    function handleFiles(files) {
        totalFiles += files.length;
        updateStatus();

        for (let file of files) {
            uploadFile(file);
        }
    }

    function uploadFile(file) {
        let formData = new FormData();
        formData.append("file", file);

        let fileExt = file.name.split('.').pop().toUpperCase();

        let fileItem = $(`
            <div class="file-item">
                <div class="file-icon">${fileExt}</div>
                <div class="file-info">
                    <div class="file-name">${file.name}</div>
                    <div class="file-size">${(file.size / 1024).toFixed(2)} KB • Uploading...</div>
                    <div class="progress-container">
                        <div class="progress-bar"></div>
                    </div>
                </div>
                <span class="cancel-btn">X</span>
                <span class="delete-btn"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-trash-fill" viewBox="0 0 16 16">
  <path d="M2.5 1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1H3v9a2 2 0 0 0 2 2h6a2 2 0 0 0 2-2V4h.5a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1H10a1 1 0 0 0-1-1H7a1 1 0 0 0-1 1zm3 4a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 .5-.5M8 5a.5.5 0 0 1 .5.5v7a.5.5 0 0 1-1 0v-7A.5.5 0 0 1 8 5m3 .5v7a.5.5 0 0 1-1 0v-7a.5.5 0 0 1 1 0"/>
</svg></span>
            </div>
        `);

        fileList.append(fileItem);

        let progressBar = fileItem.find(".progress-bar");
        let fileSizeText = fileItem.find(".file-size");
        let cancelBtn = fileItem.find(".cancel-btn");
        let deleteBtn = fileItem.find(".delete-btn");

        let xhr = new XMLHttpRequest();
        xhr.open("POST", "upload.php", true);

        xhr.upload.onprogress = function (e) {
            if (e.lengthComputable) {
                let percent = (e.loaded / e.total) * 100;
                progressBar.css("width", percent + "%");
                fileSizeText.text(`${(e.loaded / 1024).toFixed(2)} KB / ${(file.size / 1024).toFixed(2)} KB • Uploading...`);
            }
        };

        xhr.onload = function () {
            if (xhr.status == 200) {
                let response = JSON.parse(xhr.responseText);
                if (response.status === "success") {
                    progressBar.css("background", "#28a745");
                    fileSizeText.text(`${(file.size / 1024).toFixed(2)} KB / ${(file.size / 1024).toFixed(2)} KB • Completed`);
                    completedFiles++;
                    updateStatus();

                    cancelBtn.hide();
                    deleteBtn.show();

                    deleteBtn.on("click", function () {
                        deleteFile(response.file_path, fileItem);
                    });
                } else {
                    progressBar.css("background", "red");
                    fileSizeText.text("Upload Failed");
                }
            }
        };

        cancelBtn.on("click", function () {
            xhr.abort();
            fileItem.remove();
            totalFiles--;
            updateStatus();
        });

        xhr.send(formData);
    }

    function deleteFile(filePath, fileItem) {
        $.ajax({
            url: "upload.php",
            type: "POST",
            data: { delete: true, file_path: filePath },
            success: function (response) {
                let res = JSON.parse(response);
                if (res.status === "success") {
                    fileItem.remove();
                    totalFiles--;
                    completedFiles--;
                    updateStatus();
                }
            }
        });
    }

    function updateStatus() {
        statusBar.text(`Files Uploaded: ${totalFiles} / Completed: ${completedFiles}`);
    }
});



Step 3: PHP Backend to Handle Uploads 

 

Multiple File Uploading with Progress Bar in HTML CSS and JavaScript

 

 

Now, let’s handle the uploaded files on the server with upload.php 

 

 


<?php
// Database connection using PDO (Update with your database credentials)
$host = 'localhost';
$dbname = 'file_uploads';
$username = 'root';  // Change this if needed
$password = '';  // Change this if needed

try {
    $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8", $username, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    die(json_encode(["status" => "error", "message" => "Database connection failed."]));
}

// Create upload directory if it doesn't exist
$uploadDir = "uploads/";
if (!is_dir($uploadDir)) {
    mkdir($uploadDir, 0777, true);
}

// Handle file upload
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_FILES['file'])) {
    $file = $_FILES['file'];
    $fileName = basename($file['name']);
    $fileSize = $file['size'];
    $fileTmp = $file['tmp_name'];
    $fileExt = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));

    $allowedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'pdf', 'docx', 'txt', 'zip', 'mp4'];
    $maxSize = 10 * 1024 * 1024; // 10MB max file size

    if (!in_array($fileExt, $allowedExtensions)) {
        echo json_encode(["status" => "error", "message" => "Invalid file type."]);
        exit;
    }

    if ($fileSize > $maxSize) {
        echo json_encode(["status" => "error", "message" => "File size exceeds the 10MB limit."]);
        exit;
    }

    // Generate unique file name
    $uniqueName = uniqid() . "." . $fileExt;
    $filePath = $uploadDir . $uniqueName;

    // Move file to server
    if (move_uploaded_file($fileTmp, $filePath)) {
        // Insert into database
        $stmt = $pdo->prepare("INSERT INTO uploads (file_name, file_size, file_type, file_path, uploaded_at) VALUES (?, ?, ?, ?, NOW())");
        $stmt->execute([$fileName, $fileSize, $fileExt, $filePath]);

        echo json_encode(["status" => "success", "message" => "File uploaded successfully.", "file_name" => $fileName, "file_path" => $filePath]);
    } else {
        echo json_encode(["status" => "error", "message" => "Failed to move uploaded file."]);
    }
    exit;
}

// Handle file deletion
if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST['delete']) && isset($_POST['file_path'])) {
    $filePath = $_POST['file_path'];

    // Check if file exists
    if (file_exists($filePath)) {
        unlink($filePath); // Delete file from server

        // Delete from database
        $stmt = $pdo->prepare("DELETE FROM uploads WHERE file_path = ?");
        $stmt->execute([$filePath]);

        echo json_encode(["status" => "success", "message" => "File deleted successfully."]);
    } else {
        echo json_encode(["status" => "error", "message" => "File not found."]);
    }
    exit;
}

echo json_encode(["status" => "error", "message" => "Invalid request."]);
?>




Here MySQL Database Table code:



CREATE TABLE `uploaded_files` (
  `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
  `file_name` varchar(255) NOT NULL,
  `uploaded_at` timestamp NOT NULL DEFAULT current_timestamp()
) 




Done! 

Boom! 

 

You just built a Multiple File Uploading System with a Progress Bar using HTML, CSS, JavaScript, and PHP. The script allows users to drag and drop files, see upload progress, and delete uploaded files. Now you can enhance it by: 

 

Adding a database to store uploads 

 

Showing file preview for images 

 

Restricting file types and sizes 

 

Hope you had fun building this!

chandrakumar

Hi, Am Chandra Kumar, I have completed my graduation in B.E computer science and Engineering. I am the founder of Dailyaspirants and I have been doing blogging and website design and development .since 2018 and 8+experience gained in this field.

*

Post a Comment (0)
Previous Post Next Post