Fix: input file overwrite in merge (#2335)

* Fix input files being overwritten by newly uploaded files

- Fix a bug that caused existing selected/uploaded files to be overwritten when a new input file is uploaded through input element.
- Add source property to change event to differentiate between uploaded files using input element and drag/drop uploads to avoid processing drag/drop files more than once, thus avoiding file duplication (file duplication resulting from copying drop/drop files to input files on each 'change' event).

* Dispatch and use file-input-change instead of change event for merging

- Dispatch "file-input-change" event after each "change" event in file upload, to notify other functions/components relying on the files provided by the \<input\> element.
- Use "file-input-change" instead of "change" event to display the latest version of uploaded files.

# FAQ:
- Why use "file-input-change" instead of "change" in merge.js?
= "change" event is automatically triggered when a file is uploaded through \<input\> element which would replace all the existing selected/uploaded files including the drag/drop files.

## Example:
Let's say that the user wants to upload/select the x.pdf, y.pdf and z.pdf all together:

- user selects "x.pdf" -> file selected successfully.
= selected files: x.pdf

- user drags and drops "y.pdf" -> file dropped successfully
= selected files: x.pdf, y.pdf

- user selects again using \<input\> "z.pdf" -> file selected succesfully overwriting selected files.
= selected files: z.pdf
This commit is contained in:
Omar Ahmed Hassan 2024-11-26 22:41:08 +02:00 committed by GitHub
parent 86fa404c90
commit 654bc94d44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 17 additions and 3 deletions

View File

@ -64,7 +64,7 @@ function setupFileInput(chooser) {
dragCounter = 0;
fileInput.dispatchEvent(new Event("change", { bubbles: true }));
fileInput.dispatchEvent(new CustomEvent("change", { bubbles: true, detail: {source: 'drag-drop'} }));
};
["dragenter", "dragover", "dragleave", "drop"].forEach((eventName) => {
@ -81,8 +81,22 @@ function setupFileInput(chooser) {
document.body.addEventListener("drop", dropListener);
$("#" + elementId).on("change", function (e) {
allFiles = Array.from(e.target.files);
let element = e.target;
const isDragAndDrop = e.detail?.source == 'drag-drop';
if (element instanceof HTMLInputElement && element.hasAttribute("multiple")) {
allFiles = isDragAndDrop ? allFiles : [... allFiles, ... element.files];
} else {
allFiles = Array.from(isDragAndDrop ? allFiles : element.files[0]);
}
if (!isDragAndDrop) {
let dataTransfer = new DataTransfer();
allFiles.forEach(file => dataTransfer.items.add(file));
element.files = dataTransfer.files;
}
handleFileInputChange(this);
this.dispatchEvent(new CustomEvent("file-input-change", { bubbles: true }));
});
function handleFileInputChange(inputElement) {

View File

@ -3,7 +3,7 @@ let currentSort = {
descending: false,
};
document.getElementById("fileInput-input").addEventListener("change", function () {
document.getElementById("fileInput-input").addEventListener("file-input-change", function () {
var files = this.files;
displayFiles(files);
});