10

In this W3schools example, console.log on the input element reveals a FileInput object:

FileList {0: File, 1: File, length: 2}

How can I work with this? The example demonstrates accessing the file, but every time a user selects new files, the old files disappear. How can I create a new empty FileList and copy it over, so that a user can add more files to the FileList?

I tried this, but it results in two FileList objects, rather than one FileList with all the files:

var fileStore = x.files;

function myFunction(){
    var txt = "";
    if ('files' in x) {
        if (x.files.length == 0) {
            txt = "Select one or more files.";
        } else {
            fileStore += x.files;
            console.log(x.files);
            console.log(fileStore);
2
  • 1
    FileList has a readonly length, so I'm guessing it cannot be mutated: developer.mozilla.org/en-US/docs/Web/API/FileList Commented Jul 26, 2016 at 2:35
  • Ah alright, in that case I'd like to ask, how can I add those files into another variable? Commented Jul 26, 2016 at 2:36

4 Answers 4

10

Untested, but this should work

var fileStore = [];

function myFunction() {
    var txt = "";
    if ('files' in x) {
        if (x.files.length == 0) {
            txt = "Select one or more files.";
        } else {
            fileStore.push.apply(fileStore, x.files);
            console.log(x.files);
            console.log(fileStore);
        }
    }
}

More on Function::apply

More on Array::push

Sign up to request clarification or add additional context in comments.

2 Comments

This worked! Thanks for the docs. I have to wait 6 minutes until it lets me accept an answer.
best and easiest solution.
8

it is possible to add files using the datatransfer class

export const makeFileList = files => {
  const reducer = (dataTransfer, file) => {
    dataTransfer.items.add(file);
    return dataTransfer;
  }

  return files.reduce(reducer, new DataTransfer()).files;
}

2 Comments

much better than the accepted answer, thank you
yes agree with @riqitang, this is top performance solution when you are using webkitdirectory and want to filter folders with a lot of files
6

It is not possible to add File objects to FileList. You can use FormData to append Files to a single object.

var data = new FormData();
document.querySelector("input[type=file]")
.addEventListener("change", function(event) {
  for (var i = 0, files = event.target.files; i < files.length; i++) {
    data.append("file-" + [...data.keys()].length, files[i], files[i].name)
  }
})

3 Comments

Thanks. This is slightly more complicated but could ultimately prove more usable than a list since FormData has methods for deleting etc.
@DavidTan Array.prototype.splice() can add or remove an item from an array
6

An array is fine for holding onto the File instances, but FormData is better if you want to upload them somewhere. If you want to log out or view the FormData, turning it into a Map is an option. Keep in mind that FormData is iterable.

var formData = new FormData();
var index = 0;

function onDrop(event)
{
  var dt = event.dataTransfer;
  var files = dt.files;

  var count = files.length;
  output("File Count: " + count + "\n");

  for (var i = 0; i < files.length; i++) {    
    formData.append(files[i].name, files[i]);
  }
}

function output(text)
{
  document.getElementById("output").textContent += text;
  console.dir(new Map(formData));
}

See this JSBin.

1 Comment

Thanks, the JSBin is much appreciated. An answer is already accepted, but this answer is even more useful for people like myself making a javascript file uploader.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.