Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
HTML5 file uploading with multiple progress bars
HTML5 provides native file upload capabilities with progress tracking. When uploading multiple files, you can create individual progress bars for each file by leveraging the XMLHttpRequest progress events.
The Challenge
The main challenge is associating each XMLHttpRequest with its corresponding progress bar element. This requires storing a reference to the list item in the XMLHttpRequest object.
Setting Up the Progress Tracking
To track progress for multiple files, you need to bind each XMLHttpRequest to its corresponding list item element before starting the upload:
<!DOCTYPE html>
<html>
<head>
<title>Multiple File Upload with Progress</title>
<style>
.file-item {
margin: 10px 0;
padding: 10px;
border: 1px solid #ccc;
}
.progressbar {
width: 0%;
height: 20px;
background-color: #4CAF50;
transition: width 0.3s;
}
.progress-container {
width: 100%;
height: 20px;
background-color: #f0f0f0;
border-radius: 3px;
}
</style>
</head>
<body>
<input type="file" id="fileInput" multiple>
<button onclick="uploadFiles()">Upload Files</button>
<div id="fileList"></div>
<script>
function uploadFiles() {
const files = document.getElementById('fileInput').files;
const fileList = document.getElementById('fileList');
for (let i = 0; i < files.length; i++) {
const file = files[i];
// Create list item for each file
const li = document.createElement('div');
li.className = 'file-item';
li.innerHTML = `
<div>${file.name}</div>
<div class="progress-container">
<div class="progressbar"></div>
</div>
`;
fileList.appendChild(li);
// Create XMLHttpRequest and bind to list item
const xhr = new XMLHttpRequest();
xhr.upload.li = li; // Store reference to list item
// Set up progress event listener
xhr.upload.addEventListener('progress', function(e) {
if (e.lengthComputable) {
const percentComplete = parseInt(e.loaded / e.total * 100);
this.li.querySelector('.progressbar').style.width = percentComplete + '%';
}
}, false);
// Handle upload completion
xhr.addEventListener('load', function() {
this.upload.li.querySelector('.progressbar').style.backgroundColor = '#4CAF50';
console.log('Upload completed for:', file.name);
});
// Handle errors
xhr.addEventListener('error', function() {
this.upload.li.querySelector('.progressbar').style.backgroundColor = '#f44336';
console.log('Upload failed for:', file.name);
});
// Start the upload
const formData = new FormData();
formData.append('file', file);
xhr.open('POST', '/upload');
xhr.send(formData);
}
}
</script>
</body>
</html>
Key Implementation Points
The critical part is binding the list item reference to the XMLHttpRequest upload object:
<script>
// Create XMLHttpRequest and store reference
var xhr = new XMLHttpRequest();
xhr.upload.li = li; // Bind list item to xhr
// Progress event can now access the correct element
xhr.upload.addEventListener('progress', function(e) {
var percentComplete = parseInt(e.loaded / e.total * 100);
this.li.querySelector(".progressbar").style.width = percentComplete + "%";
}, false);
</script>
How It Works
When the progress event fires, this refers to the xhr.upload object. Since we stored the list item reference as xhr.upload.li, we can access it through this.li and update the correct progress bar.
Browser Compatibility
This approach works in all modern browsers that support HTML5 file uploads and XMLHttpRequest Level 2. The progress events are well-supported across Chrome, Firefox, Safari, and Edge.
Conclusion
By storing a reference to each list item in its corresponding XMLHttpRequest object, you can easily track individual file upload progress. This technique ensures each progress bar updates correctly for its associated file.
