From 654bc94d44f5c1d4e729c76ec378daa98de6c69d Mon Sep 17 00:00:00 2001 From: Omar Ahmed Hassan <98468609+omar-ahmed42@users.noreply.github.com> Date: Tue, 26 Nov 2024 22:41:08 +0200 Subject: [PATCH] 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 \ 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 \ 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 \ "z.pdf" -> file selected succesfully overwriting selected files. = selected files: z.pdf --- src/main/resources/static/js/fileInput.js | 18 ++++++++++++++++-- src/main/resources/static/js/merge.js | 2 +- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/resources/static/js/fileInput.js b/src/main/resources/static/js/fileInput.js index 001c8f24..1e537dfc 100644 --- a/src/main/resources/static/js/fileInput.js +++ b/src/main/resources/static/js/fileInput.js @@ -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) { diff --git a/src/main/resources/static/js/merge.js b/src/main/resources/static/js/merge.js index 8c263da6..d1c5fabf 100644 --- a/src/main/resources/static/js/merge.js +++ b/src/main/resources/static/js/merge.js @@ -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); });