Lightweight JavaScript library that transforms HTML elements into drag-and-drop file upload zones with thumbnail previews, progress tracking, and extensive customization options.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Upload queue management, file processing, and upload control functionality for handling file uploads to the server.
Process the upload queue with configurable parallel uploads and queue management.
/**
* Process all files in the upload queue
*/
processQueue(): void;
/**
* Process a single file
* @param file - File to process
*/
processFile(file: File): void;
/**
* Process multiple files
* @param files - Array of files to process
*/
processFiles(files: File[]): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
autoProcessQueue: false, // Manual queue processing
parallelUploads: 3 // Process up to 3 files simultaneously
});
// Process queue manually
document.getElementById("upload-btn").addEventListener("click", () => {
dropzone.processQueue();
});
// Process specific files
const selectedFiles = dropzone.getQueuedFiles().slice(0, 2);
dropzone.processFiles(selectedFiles);
// Process single file
dropzone.on("addedfile", function(file) {
if (file.type.startsWith("image/")) {
// Process images immediately
dropzone.processFile(file);
}
});Direct upload methods and upload cancellation.
/**
* Upload a single file
* @param file - File to upload
*/
uploadFile(file: File): void;
/**
* Upload multiple files
* @param files - Array of files to upload
*/
uploadFiles(files: File[]): void;
/**
* Cancel an ongoing upload
* @param file - File upload to cancel
*/
cancelUpload(file: File): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
autoProcessQueue: false
});
// Direct upload without queue
dropzone.on("addedfile", function(file) {
if (file.size < 1024 * 1024) { // Upload small files immediately
dropzone.uploadFile(file);
}
});
// Batch upload
const filesToUpload = dropzone.getAcceptedFiles();
dropzone.uploadFiles(filesToUpload);
// Cancel upload functionality
dropzone.on("addedfile", function(file) {
const cancelBtn = document.createElement("button");
cancelBtn.innerHTML = "Cancel";
cancelBtn.onclick = () => dropzone.cancelUpload(file);
file.previewElement.appendChild(cancelBtn);
});
// Cancel all uploads
function cancelAllUploads() {
dropzone.getUploadingFiles().forEach(file => {
dropzone.cancelUpload(file);
});
}Configure upload behavior and parameters.
interface UploadOptions {
/** Upload URL */
url: string;
/** HTTP method (default: "post") */
method?: string;
/** Whether to send credentials with CORS requests */
withCredentials?: boolean;
/** Maximum number of parallel uploads */
parallelUploads?: number;
/** Whether to send multiple files in one request */
uploadMultiple?: boolean;
/** Parameter name for the file */
paramName?: string;
/** Additional parameters to send */
params?: object;
/** Custom headers for upload requests */
headers?: object;
/** Whether to automatically process the queue */
autoProcessQueue?: boolean;
/** Timeout for upload requests in milliseconds */
timeout?: number;
}Usage Examples:
// Standard upload configuration
const dropzone = new Dropzone("#my-dropzone", {
url: "/api/upload",
method: "PUT",
parallelUploads: 5,
params: {
userId: "123",
category: "documents"
},
headers: {
"Authorization": "Bearer " + token,
"X-Custom-Header": "value"
}
});
// Multiple file upload in single request
const multiUploadDropzone = new Dropzone("#multi-upload", {
url: "/api/batch-upload",
uploadMultiple: true,
parallelUploads: 1, // Only one batch at a time
paramName: "files" // All files under 'files' parameter
});
// Custom parameter names for multiple files
const customParamDropzone = new Dropzone("#custom-params", {
url: "/upload",
paramName: function(n) {
return "file_" + n; // file_0, file_1, etc.
}
});Monitor upload progress and handle progress events.
/**
* Update total upload progress across all files
*/
updateTotalUploadProgress(): void;
// Progress tracking through events
on("uploadprogress", (file: File, progress: number, bytesSent: number) => void): void;
on("totaluploadprogress", (totalProgress: number, totalBytes: number, totalBytesSent: number) => void): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", { url: "/upload" });
// Track individual file progress
dropzone.on("uploadprogress", function(file, progress, bytesSent) {
console.log(`${file.name}: ${Math.round(progress)}% (${bytesSent} bytes sent)`);
// Update progress bar
const progressBar = file.previewElement.querySelector(".progress-bar");
if (progressBar) {
progressBar.style.width = progress + "%";
}
});
// Track total progress across all files
dropzone.on("totaluploadprogress", function(totalProgress, totalBytes, totalBytesSent) {
console.log(`Total: ${Math.round(totalProgress)}% (${totalBytesSent}/${totalBytes} bytes)`);
// Update overall progress indicator
document.getElementById("total-progress").style.width = totalProgress + "%";
});
// Manual progress update
dropzone.updateTotalUploadProgress();Handle upload requests and responses.
/**
* Submit the upload request
* @param xhr - XMLHttpRequest object
* @param formData - FormData containing files and parameters
* @param files - Array of files being uploaded
*/
submitRequest(xhr: XMLHttpRequest, formData: FormData, files: File[]): void;
/**
* Handle successful upload completion
* @param files - Uploaded files
* @param responseText - Server response
* @param e - XMLHttpRequest event
*/
_finished(files: File[], responseText: string, e: Event): void;
/**
* Handle upload errors
* @param files - Files that failed
* @param message - Error message
* @param xhr - XMLHttpRequest object
*/
_errorProcessing(files: File[], message: string, xhr?: XMLHttpRequest): void;Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
// Custom request handling
init: function() {
this.on("sending", function(file, xhr, formData) {
// Modify request before sending
formData.append("timestamp", Date.now());
formData.append("fileId", generateUniqueId());
// Custom headers
xhr.setRequestHeader("X-File-Name", file.name);
});
this.on("success", function(file, response) {
console.log("Upload successful:", response);
// Parse JSON response
try {
const data = JSON.parse(response);
file.serverId = data.id;
file.serverUrl = data.url;
} catch (e) {
console.log("Response is not JSON:", response);
}
});
this.on("error", function(file, errorMessage, xhr) {
console.error("Upload failed:", errorMessage);
if (xhr) {
console.error("Status:", xhr.status);
console.error("Response:", xhr.responseText);
}
});
}
});
// Custom request processing
function customSubmitRequest(xhr, formData, files) {
// Add authentication
xhr.setRequestHeader("Authorization", "Bearer " + getAuthToken());
// Add CSRF token
formData.append("_token", getCsrfToken());
// Custom upload logic
xhr.upload.addEventListener("progress", function(e) {
if (e.lengthComputable) {
const progress = (e.loaded / e.total) * 100;
console.log("Custom progress:", progress);
}
});
}Advanced queue management and processing control.
/**
* Get files associated with specific XMLHttpRequest
* @param xhr - XMLHttpRequest object
*/
_getFilesWithXhr(xhr: XMLHttpRequest): File[];Usage Examples:
const dropzone = new Dropzone("#my-dropzone", {
url: "/upload",
parallelUploads: 2,
init: function() {
// Custom queue management
this.on("processing", function(file) {
console.log("Started processing:", file.name);
// Track processing files
if (!this.processingFiles) {
this.processingFiles = new Set();
}
this.processingFiles.add(file);
});
this.on("queuecomplete", function() {
console.log("All files processed");
this.processingFiles.clear();
});
// Handle upload errors with retry logic
this.on("error", function(file, errorMessage, xhr) {
if (xhr && xhr.status >= 500) {
// Server error - retry upload
setTimeout(() => {
this.enqueueFile(file);
}, 5000);
}
});
}
});
// Pause/resume queue processing
function pauseUploads(dropzone) {
dropzone.autoProcessQueue = false;
// Cancel current uploads
dropzone.getUploadingFiles().forEach(file => {
dropzone.cancelUpload(file);
});
}
function resumeUploads(dropzone) {
dropzone.autoProcessQueue = true;
dropzone.processQueue();
}Handle multiple files in single requests.
// Configuration for batch uploads
interface BatchUploadOptions {
uploadMultiple: true;
parallelUploads: number; // Number of batches to process simultaneously
maxFiles?: number; // Total file limit
}Usage Examples:
// Batch upload configuration
const batchDropzone = new Dropzone("#batch-upload", {
url: "/api/batch-upload",
uploadMultiple: true,
parallelUploads: 1, // One batch at a time
maxFiles: 20,
init: function() {
this.on("sendingmultiple", function(files, xhr, formData) {
console.log("Sending batch of", files.length, "files");
formData.append("batchId", generateBatchId());
});
this.on("successmultiple", function(files, response) {
console.log("Batch upload successful:", response);
files.forEach((file, index) => {
file.serverId = response.ids[index];
});
});
this.on("errormultiple", function(files, errorMessage) {
console.error("Batch upload failed:", errorMessage);
// Handle batch failures
});
}
});
// Process files in custom batches
function processBatches(dropzone, batchSize = 5) {
const queuedFiles = dropzone.getQueuedFiles();
for (let i = 0; i < queuedFiles.length; i += batchSize) {
const batch = queuedFiles.slice(i, i + batchSize);
dropzone.processFiles(batch);
}
}Install with Tessl CLI
npx tessl i tessl/npm-dropzone