I have:
<input type="file" id="f" name="f" onchange="c()" multiple />
Every time the user selects a file(s), I build a list of all the selected files by pushing each element of f.files
to an array:
var Files = [];
function c() {
for (var i=0;i<this.files.length;i++) {
Files.push(this.files[i]);
};
}
At form submit, f.files
contains only the item(s) from the last select action, so I will need to update f.files
with the list of FileList
items I have accumulated:
const upload=document.getElementById("f");
upload.files = files;
But the second line gives:
Uncaught TypeError: Failed to set the 'files' property on 'HTMLInputElement': The provided value is not of type 'FileList'.
It is not happy that I am assigning it an array. How can I construct a FileList
object from the list of FileList
elements I have earlier collected?
Side question: I thought Javascript uses dynamic types. Why is it complaining about the wrong type here?
It's like you said
Failed to set the 'files' property on 'HTMLInputElement': The provided value is not of type 'FileList'.
you can only set the files with a FileList instance, unfortunately the FileList is not constructible or changeable, but there is a way to get one in a round about way
/** @params {File[]} files - Array of files to add to the FileList */
function fileListFrom (files) {
const b = new ClipboardEvent("").clipboardData || new DataTransfer()
for (const file of files) b.items.add(file)
return b.files
}
const fileList = fileListFrom([
new File(['content'], 'sample1.txt'),
new File(['abc'], 'sample2.txt')
])
fileInput.onchange = console.log
fileInput.files = fileList
console.log(fileInput.files)
<input type="file" id="fileInput" multiple />
EDIT: Setting input.files
might trigger a change event. (seems to have been fixed now) so you might want to toggle the change event listener on and off. (But might not have to anymore. Included a change listener to the demo)