Saturday, 3 December 2022

Slice An Array In A Change Event Listener For Files When The Total Allowed Number Of Files Is Added In More Than One Go - JavaScript

I have a form that takes file uploads and it currently has a limit of 10 files per upload. There are PHP validations in the backend for this too.

When more than 10 files are attached, I currently have a JavaScript slice(0, 10) method inside a change event for the file input element, which removes any files (and their preview image thumbnails) when the number attached is more than 10 files.

// For each added file, add it to submitData (the DataTransfer Object), if not already present
[...e.target.files].slice(0,10).forEach((file) => {
    if (currentSubmitData.every((currFile) => currFile.name !== file.name)) {
        submitData.items.add(file);
    }
});

The Issue

What I can’t seem to do though is work out a way to slice() the files array in a compound attachment situation, i.e. if 8 files are attached initially, and then the user decides to add another 4 prior to submitting the form, taking the total to 12. The current slice only happens when more than 10 are added in one go.

I have a decode() method that runs inside a loop (for every image attached) that carries out frontend validations, and a promiseAllSettled() method that waits for the last image to be attached prior to outputting a main error message telling the user to check the specific errors on the page.

Question

How do I slice the array on the total number of files appended, if the user has initially attached a file count less than 10, then attaches further files taking it more than 10 prior to form submission?

const attachFiles = document.getElementById('attach-files'), // file input element
dropZone = document.getElementById('dropzone'),

submitData = new DataTransfer();

dropZone.addEventListener('click', () => {
    // assigns the dropzone to the hidden 'files' input element/file picker
    attachFiles.click();
});

attachFiles.addEventListener('change', (e) => {

    const currentSubmitData = Array.from(submitData.files);

    console.log(e.target.files.length);

    // For each added file, add it to 'submitData' if not already present (maximum of 10 files with slice(0, 10)
    [...e.target.files].slice(0,10).forEach((file) => {
        if (currentSubmitData.every((currFile) => currFile.name !== file.name)) {
            submitData.items.add(file);
        }
    });

    // Sync attachFiles FileList with submitData FileList
    attachFiles.files = submitData.files;

    // Clear the previewWrapper before generating new previews
    previewWrapper.replaceChildren();

    // the 'decode()' function inside the 'showFiles()' function is returned
    // we wait for all of the promises for each image to settle 
    Promise.allSettled([...submitData.files].map(showFiles)).then((results) => {

        // output main error message at top of page alerting user to error messages attached to images

    });
    
}); // end of 'change' event listener
    
function showFiles(file) {

    // code to generate image previews and append them to the 'previewWrapper'

    // then use the decode() method that returns a promise and do JS validations on the preview images
    return  previewImage.decode().then(() => {
    
        // preform JS validations and append
    
        }).catch((error) => {
            console.log(error)
        });

} // end of showfiles(file)


from Slice An Array In A Change Event Listener For Files When The Total Allowed Number Of Files Is Added In More Than One Go - JavaScript

No comments:

Post a Comment