12

I'm using XMLHttpRequest (with jQuery) to get the upload progress of multiple files. By adding a "progress" event listener to the XMLHttpRequest object I can get event.loaded and event.total. Those variables give me the loaded and total bytes of all the files combined.

What I'd like to do is get the progress of each individual file, but from what I can see that information isn't available with XMLHttpRequest. Is that true?

I don't think this is even necessary, but here's my code:

var xhr = $.ajaxSettings.xhr();
if (xhr.upload) {
    xhr.upload.addEventListener('progress', function(event) {
        var percent = 0;
        var position = event.loaded || event.position;
        var total = event.total;
        if (event.lengthComputable) {
            percent = Math.ceil(position / total * 100);
        }
        updateProgressBar(percent);
    }, false);
}
return xhr;

If I can accomplish this with XMLHttpRequest that would be great. Any info on this would be appreciated.

Gavin
  • 7,544
  • 4
  • 52
  • 72
  • 1
    Take a look at this: [How to get progress from XMLHttpRequest](http://stackoverflow.com/questions/76976/how-to-get-progress-from-xmlhttprequest) – Joe Aug 01 '13 at 14:11
  • Thanks, but my script already does that. What I mean is I want the progress for each individual file, not all the files as a group. – Gavin Aug 01 '13 at 14:14
  • 3
    Then only send one file per request. – Ray Nicholus Aug 01 '13 at 14:19
  • It appears as though the $.ajaxSettings.xhr() object is global. You're not creating a unique instance of it, so how will it know which file you're referring to? – Gavin Aug 01 '13 at 16:36
  • 4
    @Gavin you will have to run `$.post()` or `$.ajax()` **for each file you want to upload**. That is the only way to get individual `progress` events for the files. The `progress` event is related to the full XMLHttpRequest, it doesn't know or care about how many different "parts" or "files" are being uploaded; To the XHR, it's just binary. So to be able to know the progress of individual files you must only include a single file per request. – idbehold Aug 01 '13 at 18:25
  • Thanks for that, idbehold. I was thinking about this method before, however I want to use a multiple file input, so they can select more than one file with a single file input. Due to browser security, I can't transfer the selected files each into their own dynamically created file input and create a request for each file. Using multiple ajax requests seems like it will only work if I have multiple file inputs in the HTML, one for each file, instead of a single multiple file input, right? – Gavin Aug 01 '13 at 20:22
  • @idbehold you are totally correct. No way to show progress for each file in a single bulk upload. – codemon Jan 30 '22 at 14:29

2 Answers2

1

This is what i use,

$.ajax({
    xhr: function () {
        myXhr = $.ajaxSettings.xhr();
        myXhr.addEventListener('progress', function (e) { }, false);
        if (myXhr.upload) {
            myXhr.upload.onprogress = function (e) {
                var completed = 0;
                if (e.lengthComputable) {
                    var done = e.position || e.loaded,
                        total = e.totalSize || e.total;
                    completed = Math.round((done / total * 1000) / 10);
                }
                console.log(completed); // Displays the completed percentage
            }
        }
        return myXhr;
    }
});
Balaji Viswanath
  • 1,684
  • 1
  • 12
  • 19
0

You can use Javascript plugin Dropzone.js. He handle file one by one, display progress bar for each files, easy to integrate, support mobile, drag-and-drop, ...

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.dropzonejs.com/new-js/dropzone.js"></script>
<link rel="stylesheet" href="http://www.dropzonejs.com/css/dropzone.css" />
<link rel="stylesheet" href="http://www.dropzonejs.com/css/style.css" />

<form action="/page_where_upload" class="dropzone">
  <div class="fallback">
    <input name="file" type="file" multiple />
  </div>
</form>

If you try to run the snippet, you will get an server error because page_where_upload don't exist!

Camille
  • 2,439
  • 1
  • 14
  • 32