How to get multiple files from user separately?

Daniil

Currently, I'm developing a drag and drop feature. The problem is that I can't figure out how to get multiple files from user separately. Let's say that we have a drop zone container and when user drops there images, it assigns them to <input type="file">. Let's say, a user drops here an image and then decides to drop another image and we have to somehow add this second image to the input. I tried finding solution in the Internet(of course :)) but found nothing that solves this problem.

Here is my HTML:

<form action="" method="POST" enctype="multipart/form-data">

    <div class="drop_zone">
        <span class="drop_zone__prompt">Drop your files here</span>
        <input required name="images" type="file" multiple class="drop_zone__input">
    </div>
    <input type="submit" value="Отправить">
</form>

JavaScript:

document.querySelectorAll('.drop_zone__input').forEach(InputElement => {

    const dropZoneElement = InputElement.closest('.drop_zone');

    dropZoneElement.addEventListener('drop', e => {
        e.preventDefault();

        if (e.dataTransfer.files.length){
            InputElement.files = e.dataTransfer.files;
        }
    });

I tried this:

dropZoneElement.addEventListener('drop', e => {
    e.preventDefault();

    if (e.dataTransfer.files.length){
        myfiles = e.dataTransfer.add(InputElement.files);
        InputElement.files = myfiles;
    }
});

But it returns error saying that 'e.dataTransfer.add is not a function'

Why I tried this:

I found add() method here

And this article says:

The DataTransferItemList object is a list of DataTransferItem objects representing items being dragged. During a drag operation, each DragEvent has a dataTransfer property and that property is a DataTransferItemList.

T.J. Crowder

You can't add to the files to the input's list of files, although apparently you can replace that list as described by FZs, which largely comes to the same thing.

Another way to deal with this is to make the original input hidden via CSS and add a new input where it used to be, so it can receive new files. You can make the UI clean by listing all of the files you're going to upload separately from the input.

How you deal with on submission depends on how you're handling submission.

If you're doing a standard HTTP form submission, ensure that your server side script handles all of the files regardless of which input they came from (it will receive more than one).

If you're submitting via ajax, you can use a FormData object and append each file to it, then submit that.

Here's a quick and dirty example maintaining the files in a FormData object:

let nextFileNum = 1;
const formData = new FormData();
const fileList = document.getElementById("file-list");
document.getElementById("inputs").addEventListener("input", function() {
    let input = event.target.closest("input[type=file]");
    if (!input) {
        return;
    }
    for (const file of input.files) {
        const fileId = `file${nextFileNum++}`;
        formData.append(fileId, file, file.name);
        debugShowCurrentFiles("added");
        let div = document.createElement("div");
        // This is a Q&D sketch, needs a11y
        div.innerHTML = "<span tabindex class=delete>[X]</span><span class=filename></span>";
        div.querySelector(".filename").textContent = file.name;
        div.querySelector(".delete").addEventListener("click", function() {
            formData.delete(fileId);
            debugShowCurrentFiles("deleted");
            div.remove();
            div = null;
        });
        fileList.appendChild(div);
    }
    this.removeChild(input);
    this.insertAdjacentHTML("beforeend", input.outerHTML);
    input = null;
});
function debugShowCurrentFiles(action) {
    const contents = [...formData.entries()];
    console.log(`--- ${action}, updated formData contents (${contents.length}):`);
    for (const [key, value] of contents) {
        console.log(`${key}: ${value.name}`);
    }
}
#file-list .delete {
    margin-right: 2em;
    cursor: pointer;
}
<div id="inputs">
    <input type="file" multiple>
</div>
<div id="file-list"></div>

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How do I get user input and store it into a HashMap and create the two keys separately to print out?

How to separately get user and system environment variables in Windows with C

How to get alembic to recognise models from multiple model files in Flask

How to separately get the X, Y or Z coordinates from a pdb file

How to get input from user, then check if the multiple lists matches the input

read and write multiple files separately from the console, python

How to upload multiple files separately in Flask?

Saving multiple figures from each file for multiple files separately

How to get user`s files from 'Files' tab using system admin token (REST API)?

How to select multiple images from android gallery separately

Batch script for compressing multiple files into separately output

How to plot multiple plots separately?

How can I allow the user to store multiple CSV files in a program from user input? - Python

How to list global environment variables separately from user-specific environment variables?

Unsure how to get user input from a multiple line loop - Python

How to embed files separately?

Read Excel files and get data from the header and two tables separately

script to tar up multiple log files separately

How to get key and value separately from json in node js

How to get a combined string from multiple files

How to get a certain line from multiple files in linux?

How to get a line with a string from multiple files by file orders?

Python: How to get multiple values from user?

how to get the files from multiple input file control?

How can I get the correct birthdate format if the user inputs month, day and year separately?

How to get total audio duration from multiple audio files

Get multiple latest files from sftp server

How can I get the average for a column from multiple files in R?

Flutter how to get multiple files from path