How to Update Filelist

Is it possible to update FileList?

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 />

How to change a file input's FileList programmatically?

For security reasons, browsers prevent javascript from changing the files which will be uploaded: only the user can select files via the user interface. This is to prevent an evil script to upload /etc/passwd, for example, without the user knowing.

The one exception is that calling "reset" on the form will clear the file or filelist, but you can never add to programmatically.

How to set File objects and length property at FileList object where the files are also reflected at FormData object?

Edit:

As proven by OP, in one of their gist, there is actually a way to do it...

The DataTransfer constructor (currently only supported by Blink, and FF >= 62), should create a mutable FileList (chrome currently always return a new FileList, but it doesn't really matter for us), accessible through the DataTransferItemList.

If I'm not mistaken, this is currently the only specs-wise way to do it, but Firefox had a bug in their implementation of the ClipboardEvent constructor, where the same DataTransferItemList was and set to the mode read/write which allowed a workaround for FF < 62. I am not sure of my interpretation of the specs, but I believe it should not be accessible normally).

So the way guest271314 found to set arbitrary files on a FileList is as follows:

const dT = new DataTransfer();
dT.items.add(new File(['foo'], 'programmatically_created.txt'));
inp.files = dT.files;
<input type="file" id="inp">

Update the status of a input[type=file] when change files

It is not possible to set the value of FileList of <input type="file"> element .files programmatically; FileList is read-only

Can a file be changed after it has already been selected in input type=file and still have its text read?

No, there is no reliable way.

When selecting a file from an <input type="file"> the browser gets a pointer to the file on disk along with some metadata provided by the OS. Luckily, it doesn't save the file's data in memory (would be quite hard to upload multi-GB files otherwise), and it doesn't lock the file on disk either.

So the user can indeed edit the file on disk, and they can even remove it from the disk.
However, most browsers will use the metadata provided by the OS at the moment of picking it in order to read the file through a FileReader.

This means that if your file was 120KB when picked, then edited to make it a 100KB file, the browser will ask for data that doesn't exist anymore, and the reader will crash.

You can of course force the browser to store the full data in memory at the moment of picking it, e.g

blob = new Blob( [ await file.arrayBuffer() ], { type: file.type } );

here blob holds in memory the data that file was pointing to at the moment it's been called.

But blob is not connected anymore with the file on disk, so if your user does edit the file on disk, blob won't be changed.

Note that Firefox will actually be able to handle edited files through the Blob methods (arrayBuffer() and text()) at least on macOS (I guess OS matters here), but their FileReader will still fire an Error. Chrome just throws in both cases.
In the same way, fetching the file through XHR or fetch will throw in Chrome (but not in FF if the file only has been edited and still exists).

Update image file via file list

This behavior is done on purpose. If you do not want this, you have to either update to 6.x or use the extension dam.

The reason for this behavior is that editors cannot change content on websites that they do not have access to. The files are always copied, therefore you have a file for each record.
Also this eases working with workspaces.

You can find out your version by looking into the page title after login in to the backend. The version is displayed in the title.

Most efficient way to update a flat file list

I would think that the easiest way to do this would be to delete and recreate the file. Depending on how difficult it is to create the "summary", this could well be the fastest method since you don't need to compare or edit anything.

If the summary creation is "hard" and the database fits in memory, the easiest way to go would probably be to load the database into a dict (keyed on the filename, with data indicating whether or not the file has been "seen") and do the os.walk again, updating the dict as necessary. Then iterate the dict, writing all entries that have been seen.

(BTW the last modified field isn't necessarily useful, you have to check the file's modified time anyway so might as well compare it to the database's timestamp.)



Related Topics



Leave a reply



Submit