Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fadebowaley/e8cc9c90044130d52160d9b2eebfe978 to your computer and use it in GitHub Desktop.
Save fadebowaley/e8cc9c90044130d52160d9b2eebfe978 to your computer and use it in GitHub Desktop.
AJAX File Upload Progress Bar
<div id="up-wrap">
<div id="upload"></div>
<h1>UPLOAD PROGRESS BAR</h1>
<!-- (A) PROGRESS BAR -->
<div id="up-progress">
<div id="up-bar"></div>
<div id="up-percent">0%</div>
</div>
<div id="up-demo">* Demo only, will not actually upload.</div>
<!-- (B) FILE PICKER -->
<input type="file" id="up-file" disabled/>
<label for="up-file" id="up-label">
Select File
</label>
<!-- (X) VISIT CODE-BOXX -->
<div id="code-boxx">
Visit
<a href="https://code-boxx.com/ajax-upload-progress-bar/"
target="_blank">
Code Boxx
</a> for more details.
</div>
</div>
var uprog = {
// (A) INIT
hBar : null, // html progress bar
hPercent : null, // html upload percentage
hFile : null, // html file picker
init : () => {
// (A1) GET HTML ELEMENTS
uprog.hBar = document.getElementById("up-bar");
uprog.hPercent = document.getElementById("up-percent");
uprog.hFile = document.getElementById("up-file");
// (A2) ATTACH AJAX UPLOAD + ENABLE UPLOAD
uprog.hFile.onchange = uprog.upload;
uprog.hFile.disabled = false;
},
// (B) HELPER - UPDATE PROGRESS BAR
update : (percent) => {
percent = percent + "%";
uprog.hBar.style.width = percent;
uprog.hPercent.innerHTML = percent;
if (percent == "100%") { uprog.hFile.disabled = false; }
},
// (C) PROCESS UPLOAD
upload : async () => {
// (C1) GET FILE + UPDATE HTML INTERFACE
let file = uprog.hFile.files[0];
uprog.hFile.disabled = true; // disable upload button
uprog.hFile.value = ""; // reset file picker
// DUMMY UPLOAD DEMO
await new Promise(e=>{setTimeout(e,500)});
uprog.update(25);
await new Promise(e=>{setTimeout(e,500)});
uprog.update(50);
await new Promise(e=>{setTimeout(e,500)});
uprog.update(75);
await new Promise(e=>{setTimeout(e,500)});
uprog.update(100);
/* THIS SHOULD BE THE ACTUAL AJAX UPLOAD
// (C2) AJAX UPLOAD
let xhr = new XMLHttpRequest(),
data = new FormData();
data.append("upfile", file);
xhr.open("POST", "upload.php");
// (C3) UPLOAD PROGRESS
let percent = 0, width = 0;
xhr.upload.onloadstart = (evt) => { uprog.update(0); };
xhr.upload.onloadend = (evt) => { uprog.update(100); };
xhr.upload.onprogress = (evt) => {
percent = Math.ceil((evt.loaded / evt.total) * 100);
uprog.update(percent);
};
// (C4) ON LOAD & ERRORS
xhr.onload = function () {
if (this.response!= "OK" || this.status!=200) {
// @TODO - DO SOMETHING ON ERROR
// alert("ERROR!");
// reset form?
console.log(this);
console.log(this.response);
console.log(this.status);
} else {
uprog.update(100);
// @TODO - DO SOMETHING ON COMPLETE
}
};
// xhr.onerror = () => { DO SOMETHING };
// (C5) GO!
xhr.send(data);*/
}
};
window.addEventListener("load", uprog.init);
/* (A) WRAPPER */
#up-wrap, #up-wrap * {
font-family: arial, sans-serif;
box-sizing: border-box;
}
#up-wrap {
width: 500px;
padding: 20px;
border-radius: 20px;
background: rgba(255, 255, 255, 0.4);
}
/* (B) PROGRESS BAR */
#up-progress, #up-bar, #up-percent { height: 30px; }
#up-progress {
position: relative;
background: #fff;
}
#up-bar {
background: #d3e3ff;
width: 0;
transition: width 0.5s;
}
#up-percent {
position: absolute; top: 0; left: 0;
width: 100%; display: flex;
align-items: center; justify-content: center;
}
/* (C) FILE PICKER */
#up-file { display: none; }
#up-label {
display: inline-block;
margin-top: 20px;
padding: 10px 20px;
color: #fff;
border: 1px solid #dfdfdf;
background: #296cd0;
cursor: pointer;
}
#up-file:disabled ~ #up-label { background: #b1b1b1; }
/* (X) DOES NOT MATTER */
/* PAGE & BODY */
body {
display: flex;
align-items: center; justify-content: center;
min-height: 100vh;
background-image: url(https://images.unsplash.com/photo-1584968183745-e4c64b7df994?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTY0MjU3NTAyMQ&ixlib=rb-1.2.1&q=85);
background-repeat: no-repeat;
background-position: center;
background-size: cover;
}
/* SVG */
#upload {
width: 100%; height:100px;
background-image: url('data:image/svg+xml;utf8,<svg viewBox="0 0 640 512" width="100" xmlns="http://www.w3.org/2000/svg"><path d="M537.6 226.6c4.1-10.7 6.4-22.4 6.4-34.6 0-53-43-96-96-96-19.7 0-38.1 6-53.3 16.2C367 64.2 315.3 32 256 32c-88.4 0-160 71.6-160 160 0 2.7.1 5.4.2 8.1C40.2 219.8 0 273.2 0 336c0 79.5 64.5 144 144 144h368c70.7 0 128-57.3 128-128 0-61.9-44-113.6-102.4-125.4zM393.4 288H328v112c0 8.8-7.2 16-16 16h-48c-8.8 0-16-7.2-16-16V288h-65.4c-14.3 0-21.4-17.2-11.3-27.3l105.4-105.4c6.2-6.2 16.4-6.2 22.6 0l105.4 105.4c10.1 10.1 2.9 27.3-11.3 27.3z" /></svg>');
background-repeat: no-repeat;
background-position: center;
}
/* DEMO */
#up-wrap { text-align: center; }
#up-wrap h1 { margin: 0 0 40px 0; }
#up-demo { margin-top: 10px; }
/* FOOTER */
#code-boxx {
font-weight: 600;
margin-top: 50px;
}
#code-boxx a {
display: inline-block;
padding: 5px;
text-decoration: none;
background: #b90a0a;
color: #fff;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment