Skip to content

Instantly share code, notes, and snippets.

@lbussy
Created May 13, 2023 13:24
Show Gist options
  • Save lbussy/d0d18d1383b5df2103d3505d5498a26c to your computer and use it in GitHub Desktop.
Save lbussy/d0d18d1383b5df2103d3505d5498a26c to your computer and use it in GitHub Desktop.
JQuery-based File Upload Functions

File Upload

This demo file will allow uploading to a capable endpoint (in this case /api/v1/fs/upload/). It is styled with Bootstrap as an example of the integration.

<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<title>Upload Test</title>
</head>
<body>
<div class="container">
<!-- File upload div: -->
<!-- Use: $("#fileUpload").hide(); or $("#fileUpload").show(); -->
<div id="fileUpload" class="row">
<div class="col">
<div class="mb-3 mt-3">
<h3 class="mb-3" style="font-weight: 300">Upload File</h3>
<div class="form-group mb-3">
<div class="custom-file">
<input type="file" class="custom-file-input" name="file_input" id="file_input"
oninput="input_filename();">
<label id="file_input_label" class="custom-file-label" for="image">Select file</label>
</div>
</div>
<button onclick="upload();" id="upload_btn" class="btn btn-primary" disabled>Upload</button>
<button class="btn btn-primary d-none" id="loading_btn" type="button" disabled>
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
Uploading...
</button>
<button type="button" id="cancel_btn" class="btn btn-secondary d-none">Cancel upload</button>
</div>
<div id="progress_wrapper" class="d-none">
<label id="progress_status"></label>
<div class="progress mb-3">
<div id="progress" class="progress-bar" role="progressbar" aria-valuenow="25" aria-valuemin="0"
aria-valuemax="100"></div>
</div>
</div>
<div id="alert_wrapper"></div>
</div>
</div>
<!-- File upload div^ -->
</div>
<script>
// Get a reference to the progress bar, wrapper & status
var progress = document.getElementById("progress");
// Function to show alerts
function show_alert(message, alert) {
$("#alert_wrapper").html(`
<div id="alert" class="alert alert-${alert} alert-dismissible fade show" role="alert">
<span>${message}</span>
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div>`);
}
// Function to upload file
function upload() {
url = "/api/v1/fs/upload/";
// Reject if the file input is empty & throw alert
if (!$("#file_input").val()) {
show_alert("No file selected", "warning")
return;
}
// Create a new FormData instance
var data = new FormData();
// Create a XMLHTTPRequest instance
var request = new XMLHttpRequest();
// Set the response type
request.responseType = "text";
// Clear any existing alerts
$("#alert_wrapper").html('');
// Disable the input during upload
$("#file_input").attr("disabled", "disabled");
// Hide the upload button
$("#upload_btn").addClass("d-none");
// Show the loading button
$("#loading_btn").removeClass("d-none");
// Show the cancel button
$("#cancel_btn").removeClass("d-none");
// Show the progress bar
$("#progress_wrapper").removeClass("d-none");
// Get a reference to the file
var file = $("#file_input").prop('files')[0];
// Get a reference to the filename
var filename = file.name;
// Get a reference to the filesize & set a cookie
var filesize = file.size;
// Append the file to the FormData instance
data.append("file", file);
// Set status to waiting
$("#progress_status").text("Waiting.");
// Event Handlers:
//
// Request progress handler
request.upload.addEventListener("progress", function (e) {
// Get the loaded amount and total filesize (bytes)
var loaded = e.loaded;
var total = e.total
// Calculate percent uploaded
var percent_complete = (loaded / total) * 100;
// Update the progress text and progress bar
progress.setAttribute("style", `width: ${Math.floor(percent_complete)}%`);
$("#progress_status").text(`${Math.floor(percent_complete)}% uploaded.`);
});
// Request load handler (transfer complete success)
request.upload.addEventListener("load", function (e) {
uploadComplete();
show_alert(`${filename} uploaded.`, "success");
});
// Request error handler
request.addEventListener("error", function (e) {
uploadComplete();
$("#progress_status").text("Error.");
show_alert(`Error uploading ${filename}`, "warning");
});
// Request abort handler
request.addEventListener("abort", function (e) {
uploadComplete();
$("#progress_status").text("Cancelled.");
show_alert(`Upload of ${filename} cancelled`, "primary");
});
// Cancel event listener
$("#cancel_btn").on("click", function () {
request.abort();
})
// Open and send the request
request.open("POST", url);
request.send(data);
}
// Function to update the input placeholder
function input_filename() {
// Hide the progress bar
$("#progress_wrapper").addClass("d-none");
// Reset the progress bar state
progress.setAttribute("style", `width: 0%`);
// Reset progress text
$("#progress_status").text('');
// Clear any existing alerts
$("#alert_wrapper").html('');
// Set input to file name
$("#file_input_label").text($("#file_input").prop('files')[0].name);
// Enable upload button
$("#upload_btn").attr("disabled", false);
}
// Function to show upload complete
function uploadComplete() {
// Clear the input
$("#file_input").val('');;
// Hide the cancel button
$("#cancel_btn").addClass("d-none");
// Reset the input element
$("#file_input").removeAttr('disabled');
// Show the upload button
$("#upload_btn").removeClass("d-none");
// Hide the loading button
$("#loading_btn").addClass("d-none");
// Reset the input placeholder
$("#file_input_label").text("Select file");
// Disable input button
$("#upload_btn").attr("disabled", "disabled");
}
</script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment