0

I am uploading files and showing progress bars for each load, but it only applies to only one progress bar.

In html,

   <input type="file" id="file-input" multiple>
   <div id="file-list">
   </div>

In Javascript,

$('#file-input').change(function(e) {

for (var i = 0, f; f = files[i]; i++) {

    var reader = new FileReader();
    reader.readAsBinaryString(f);

    reader.onloadstart = function (e) {
      var text = '<div><div id="progress_bar" class="loading"><div class="percent">0%</div></div></div>';
      $('#file-list').append(text);
    }

    reader.onload = function(e) {
       var progress = document.querySelector('.percent');
       progress.style.width = '100%'; // replacing with percentage
       progress.textContent = '100%';
    }
 }

});

The result for uploading three files at once is showing one progress bar with 100% and two bars with 0%. What's wrong with this?

user2307087
  • 423
  • 11
  • 25
  • Is requirement to display progress for each `File` object? See also http://stackoverflow.com/questions/19871627/javascript-for-loop-scope-takes-last-variable . `FileReader` is asynchronous. Second file upload will not wait for first file upload to complete before starting – guest271314 Apr 18 '16 at 02:45
  • Yes, I'd like to show progress for each file being uploaded. Thanks. – user2307087 Apr 18 '16 at 03:47

1 Answers1

1

You can define f outside of for loop, adjust for loop to include condition i < f.length ; pass i to an IIFE to create a separate scope for each call to FileReader.

$("#file-input").change(function(e) {
  var f = e.target.files;
  for (var i = 0; i < f.length; i++) {
    (function(n) {
      var reader = new FileReader();
      reader.readAsBinaryString(f[n]);

      reader.onloadstart = function(e) {
        var text = "<div><div class=loading><div class=percent-" 
                   + n + ">0%</div></div></div>";
        $("#file-list").append(text + "<br>");
      }

      reader.onload = function(e) {
        var progress = $(".percent-" + n);
        progress.css("width", "100%"); // replacing with percentage
        progress.text("100%");
      }
    }(i))
  }
});
[class^="percent"] {
  width: 1%;
  height: 24px;
  background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<input type="file" id="file-input" multiple>
<div id="file-list">
</div>

See also Upload multiple image using AJAX, PHP and jQuery

Community
  • 1
  • 1
guest271314
  • 1
  • 15
  • 104
  • 177