Mko Mko - 5 months ago 18
jQuery Question

Count input files in for loop

I'm using a multiple file input and then a for loop to iterate through the files using FileReader. JSfiddle here: https://jsfiddle.net/zLq8rsos/. It shows filename en contents correctly, but I don't understand why the counting doesn't work. If I choose one file, it's numbered '1' (why not 0?). If I choose two files, they're both counted '2'. What am I doing wrong?



function showDetails(file, content, n) {
var start = content.substring(0, 9);
var message = "File " + n + " is " + file.name + " and starts with " + start + " .<br>";
$('#results').append(message);
}

$(document).ready(function() {
$('#files').on('change', function(evt) {
var files = evt.target.files;
if (files) {
$('#results').text("");
for (var i = 0, f; f = files[i]; i++) {
var reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
var content = e.target.result;
showDetails(theFile, content, i);
};
})(f);
reader.readAsText(f, "UTF-8");
}
} else {
console.log("Failed to load file(s)");
};
});
});

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="files" name="files[]" multiple>
<div id="results">
</div>




Answer

Use closures Modify IIFE

function showDetails(file, content, n) {
  var start = content.substring(0, 9);
  var message = "File " + n + " is " + file.name + " and starts with " + start + " .<br>";
  $('#results').append(message);
}

$(document).ready(function() {
  $('#files').on('change', function(evt) {
    var files = evt.target.files;
    if (files) {
        $('#results').text("");
      for (var i = 0, f; f = files[i]; i++) {
        var reader = new FileReader();
        reader.onload = (function(theFile,count) {
          return function(e) {
            var content = e.target.result;
            showDetails(theFile, content, count);
          };
        })(f,i+1);
        reader.readAsText(f, "UTF-8");
      }
    } else {
      console.log("Failed to load file(s)");
    };
  });
});