Buzut
Buzut

Reputation: 5153

XHR multiple file upload with progressbar

I'm uploading files via an input type="file" and an XHR request. Uploads proceed very well. The problem is, I can't update my progress bars with onprogress. It works well if I upload only one file, but since there's more than one, there is only one progress bar being updated, the others simply just don"t work. It might come from the for loop, but I don't see how I may fix this If anyone has an idea, that'd be great !

Here's the code:

$('input').change(function() {

var allowedTypes = ['png', 'jpg', 'jpeg', 'gif'];   
var filesLen = this.files.length;
var fileInput = document.querySelector('#file');

for (i = 0; i < filesLen; i++)
{
    var vidType = this.files[i].name.split('.');

    if (allowedTypes.indexOf(vidType[vidType.length -1].toLowerCase()) != -1)
    {
        var progress = 'progress' + i;

        $('input').before('<p>' + this.files[i].name + ' <progress id="' + progress + '"></progress></p>');

        var xhr = new XMLHttpRequest();

        xhr.open('POST', '/upload/');

        xhr.upload.onprogress = function(e) 
        {
            $('#' + progress).attr('value', e.loaded);
        $('#' + progress).attr('max', e.total);
        };

        xhr.onload = function()
        {
            console.log('upload complete');
        };

        var form = new FormData();
        form.append('title', this.files[i].name);
        form.append('pict', fileInput.files[i]);

        xhr.send(form);

    }

    else
    {
        alert('Your file "' + this.files[i].name + '" \'s format isn\'t supported');    
    }
}

Upvotes: 3

Views: 6971

Answers (1)

Dagg Nabbit
Dagg Nabbit

Reputation: 76736

This is the "infamous loop problem."

The problem is here:

xhr.upload.onprogress = function(e) 
{
    $('#' + progress).attr('value', e.loaded);
    $('#' + progress).attr('max', e.total);
};

When this function runs, progress will be whatever it was when the loop exited, not what it was at the point in the loop where the function was defined. Try replacing that code with something like this:

(function(progress) { 
    xhr.upload.onprogress = function(e) 
    {
        $('#' + progress).attr('value', e.loaded);
        $('#' + progress).attr('max', e.total);
    };
}(progress));

More: Javascript infamous Loop issue?

Upvotes: 8

Related Questions