Question

I have my code almost functional but the event listener "Progress" isn't firing and so i am unable to track the progress of my upload.

The event listener "Load" is firing and the rest of my code is executing so I'm at a loss. Does anyone have any suggestions?

$("#myForm").submit(function(){
var xhr = new XMLHttpRequest();

//Progress Tracking
xhr.upload.addEventListener("progress", function(e){
    if(e.lengthComputable){
        alert('test');
        var percentage = Math.round((e.loaded * 100) / e.total);
        $("#myProgress").innerHTML(percentage + '%');
        $("#Progress").val(percentage);
    }
}, false);

//Added just to test that something was firing.
xhr.addEventListener("load", function(){alert('load');}, false);
xhr.addEventListener("error", function(){alert('error');}, false);
xhr.addEventListener("abort", function(){alert('abort');}, false);

//Status Tracking
xhr.open(this.method, this.action, true);
xhr.setRequestHeader("X-FILENAME", this.name);
xhr.onreadystatechange = function(){
    if(xhr.readyState == 4 && xhr.status == 200){
        $('#myForm')[0].reset();
    }
};

//Submit Data
var fd = new FormData();
fd.append("text", $('#text').val());
fd.append("file", $('#file')[0].files[0]);

xhr.send(fd);
return false;
});
Was it helpful?

Solution

As your using XMLHttpRequest & FormData... so modern browsers (chrome,safari,ie10,ios,android)

here is a very short version of ajax.

function ajax(a,b,e,d,c){//Url,callback,method,formdata or{key:val},placeholder
 c=new XMLHttpRequest;
 c.onload=b;
 c.open(e||'get',a);
 c.send(d||null)
}

usage

ajax('index.html',callback);
// does a get query to index.html and calls the callback onload

ajax('upload.php',callback,'post',new FormData(form));
//posts the whole form to the upload.php and calls the callback onload

now you want the progress events.

addEventListener is good if you want to add multiple eventhandlers but as you just need one progress handler the xhr.onprogess & xhr.upload.onprogress are enough.

so:

function ajax(a,b,e,d,f,g,c){
 c=new XMLHttpRequest;
 !f||(c.upload.onprogress=f);
 !g||(c.onprogress=g);
 c.onload=b;
 c.open(e||'get',a);
 c.send(d||null)
}

in this case we destroy the usability of this previously created function but we can do alot more.

/*
a=url  -  index.php,data.json,script.js
b=callback - function(){console.log(this.response)}
e=method - post,get ?put ?delete
d=formdata or object - new FormData(form) or {key:val}
f=upload progress func - function(){console.log(e.loaded/e.total*100>>0)}
g=download progress func - ""
c=this is just a placeholder - -----
*/

Now regarding your function you just create some short code to do the rest for you:

var form;
function uploadProgress(e){
 console.log(e.lengthComputable?(e.loaded/e.total*100>>0)+'%':'NO SIZE');
}
function uploadThatStuff(){
 ajax('upload.php',finish,'post',new FormData(form),uploadProgress);
}
function finish(){
 console.log('upload finished',this.response);
}
window.onload=function(){
 form=document.getElementsByTagName('form')[0];
 form.onsubmit=uploadThatStuff;
}

just replace yourForm & upload.php ... and add also the 2nd ajax function

if you have some questions just ask

as a test php you could use

<?php
print_r(array($_FILES,$_POST,$_GET));
?>

EDIT

full working example with progress bar

<?php
if($_FILES){
 print_r(array($_FILES,$_POST));
}else{
?>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Upload</title>
<style>
body>div{
 width:300px;
 height:20px;
 border:1px solid rgba(0,0,0,0.5);
}
body>div>div{
 width:0%;
 height:100%;
 background-color:green;    
}
</style>
<script>
var form,progress,result;
function ajax(a,b,e,d,f,g,c){
 c=new XMLHttpRequest;
 !f||(c.upload.onprogress=f);
 !g||(c.onprogress=g);
 c.onload=b;
 c.open(e||'get',a);
 c.send(d||null)
}
function uploadProgress(e){
 e=e||window.event;
 progress.firstChild.style.width=((e.loaded||e.position)/(e.total||e.totalSize)*100>>0)+'%';
}
function uploadThatStuff(e){
 e=e||window.event;
 e.preventDefault();
 //form.title.value?form.file.files[0]?
 ajax('upload.php',finish,'post',new FormData(form),uploadProgress)
 //:alert('Please add a file'):alert('Please add a title');
}
function finish(e){
 result.textContent=this.response||(e=e||window.event,e.target=e.target||e.srcElement,e.target.response);
}
window.onload=function(){
 form=document.getElementsByTagName('form')[0];
 form.onsubmit=uploadThatStuff;
 progress=document.getElementsByTagName('div')[0];
 result=document.getElementsByTagName('pre')[0];
}
</script>
</head>
<body>
<form>
<input name="title">title<br>
<input type="file" name="file"><br>
<input type="submit" value="Send">
</form>
<div><div></div></div>
<pre></pre>
</body>
</html>
<?php
}
?>

past in a text file and save as upload.php

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top