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?
FileList is a command-line utility that generates a CSV file listing the contents of a given directory. By default, the list includes the file name, size, and path, as well as the last-access, last-modified, and creation dates, etc. You can easily import all results to a spreadsheet or database.
A file list is a file that contains the names and directories of each source file that you want to use in a mapping. Use a file list to enable a task to read multiple source files for one source object in a mapping.
One way to let us loop through each item in a file list object is to convert it to an array with the Array. from method. Then we can use the forEach method on it to loop through the file list entries. The file input has the multiple attribute so that we can select multiple files.
A FileList is an array-like object that represents a collection of File objects returned by the files property of the HTML <input> element. You can use this to access the list of files selected with the <input type="file"> element.
You can't modify a Filelist, but you can create a new one using a DataTransfer object, and if you wish you can copy your data into it to create a duplicate with the specific change you want to make.
let list = new DataTransfer(); let file = new File(["content"], "filename.jpg"); list.items.add(file); let myFileList = list.files;
You can then set it as the file attribute of the DOM node:
fileInput.files = myFileList;
If you wished, you could iterate over your old FileList, copying files to the new one.
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 * @return {FileList} */ function FileListItems (files) { var b = new ClipboardEvent("").clipboardData || new DataTransfer() for (var i = 0, len = files.length; i<len; i++) b.items.add(files[i]) return b.files } var files = [ new File(['content'], 'sample1.txt'), new File(['abc'], 'sample2.txt') ]; fileInput.files = new FileListItems(files) console.log(fileInput.files)
<input type="file" id="fileInput" multiple />
doing this will trigger a change event, so you might want to toggle the change event listener on and off
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With