Tuesday, 18 October 2022

Add Further Selection Of Files From FilePicker To Existing Array Created With DataTransfer - JavaScript

I have a file uploader that when an image is removed from the images previews, this image is removed from the FileList. This done by creating a new array and removing the target (deleted) element from the new array and then using dataTranser() to set this as the 'file' input element's FileList. All of the is works OK.

The Problem

The issue I have is if further files are added via the filepicker input element prior to submission (irrespective of if any have been deleted), even though the images previews are correct in terms of the number of and specific images shown, the files that are uploaded/submitted are always the files added with the most recent selection. If only one set of files are selected this of course is fine, but if additional images/files are added prior to submission this second set overrides the first set (despite the images still showing correctly in the image preview).

To see the problem if you select files to upload via the 'browse' button in the code example, and then click the 'browse' button a second time to add further images, you'll see what I mean.

The Question

How I get it so that when a second selection of files are added these are added to the existing array and don't override it?

Note 1: to keep the code simpler I've set it so the image is removed when the specific image preview is clicked, and not via a 'remove image' button.

Note 2: the backend code used to process the form is PHP, but I haven't included this because it isn't part of the problem.

Codepen: https://codepen.io/thechewy/pen/wvjOdEq

let attachFiles = document.getElementById("attach-files");
let previewWrapper = document.getElementById("show-selected-images");
let form = document.getElementById("upload-images-form");

attachFiles.addEventListener("change", (e) => {
  [...e.target.files].forEach(showFiles);
});

function showFiles(file) {
  let previewImage = new Image();

  previewImage.dataset.name = file.name;
  previewImage.classList.add("img");
  previewImage.src = URL.createObjectURL(file);

  previewWrapper.append(previewImage); // append preview image

  // -- remove the image preview visually and change FileList
  document.querySelectorAll(".img").forEach((i) => {
    i.addEventListener("click", (e) => {
      const transfer = new DataTransfer();
      const name = e.target.dataset.name;

      for (const file of attachFiles.files) {
        if (file.name !== name) {
          transfer.items.add(file);
        }
      }

      attachFiles.files = transfer.files;

      //remove image preview element when image is clicked
      e.target.remove();
    });
  });
}
form {
  padding: 1rem 2rem;
  width: 50%;
  border: 1px solid;
}

input,
button {
  display: block;
  margin: 2rem 0;
}

.img {
  width: 200px;
  height: 200px;
  object-fit: cover;
  margin: 0 1rem;
}

img:hover {
  cursor: pointer;
}
<form enctype="multipart/form-data" method="post" id="upload-images-form">
  <input id="attach-files" type="file" name="attach-files[]" multiple>
  <button name="submit" id="submit">SUBMIT</button>
  <div id="show-selected-images"></div>
</form>


from Add Further Selection Of Files From FilePicker To Existing Array Created With DataTransfer - JavaScript

No comments:

Post a Comment