0

THE CASE

I am building an image upload with preview. On selecting multiple images, a preview is generated with a delete icon. This is working. The problem is the input file field is not counting correctly when deleting files from the image array.

THE CODE

The input HTML:

<input type="file" class="form-control" id="image" name="image[]" multiple>

Then, the code I got from (https://stackoverflow.com/a/68252788/910654). Here files are deleted when clicking 'onclick=deleteFile'.

--> Also working, however: the input field is not updating the count correctly when using more than three images. It gets stuck on 2 or 3 in the input field when deleting an item (given as: [i]).

function deleteFile(index)  {
    filelistall = $('#image').prop("files");
    var fileBuffer=[];
    Array.prototype.push.apply( fileBuffer, filelistall );
    fileBuffer.splice(index, 1);
    const dT = new ClipboardEvent('').clipboardData || new DataTransfer(); 
    for (let file of fileBuffer) { dT.items.add(file); }
    filelistall = $('#image').prop("files",dT.files);
    $("#image-row-"+index).hide();
}

When selecting multiple images, this shows the previews correctly:

$('#image').change(function(){
    $("#preview").html('');
    for (var i = 0; i < $(this)[0].files.length; i++) {
    var name = this.files[i].name;
    $("#preview").append('<div class="row mt-2" id="image-row-'+[i]+'">
            <div class="col-2"><img src="'+window.URL.createObjectURL(this.files[i])+'" class="img-fluid"/></div>
            <div class="col-8">&nbsp; '+ name+'</div>
            <div onclick=deleteFile('+[i]+') class="col-2 deleteFile" data-name="'+[i]+'"><i class="mdi mdi-delete mdi-24px"></i></div>
        </div>');
    }
});

THE QUESTION

Does anyone know how to get the deleteFile() function to count correctly when deleting files?

vvvvv
  • 25,404
  • 19
  • 49
  • 81
KJS
  • 1,176
  • 1
  • 13
  • 29
  • 1
    you can't mod the input's `.files` property directly, it's set by the file chooser dialog. you _can_ however .slice() (clone) it into a "real" array and tack it onto the input (aka `$(this)[0]`) as `input._files`, then you can push, pop, splice etc away on that and it will work as expected. – dandavis Jun 22 '22 at 22:00
  • Yeah, that's kind of the reason me asking this here, haha! My knowledge on this is less than sufficient, or better: crap even. – KJS Jun 22 '22 at 22:18

1 Answers1

0

I found the solution for this problem a day later.

As it turns out, the 'change' detection on #image as a file type field, only does a refresh on the uploaded files in the input field.

So, on every delete - with: onclick=deleteFile('+[i]+'), as above here - you can run it again with:

$("#image").trigger("change");

Would still be great to learn how this actually works in browsers, but for now it does the trick flawlessly!

Updated the question with a clear note as well.

KJS
  • 1,176
  • 1
  • 13
  • 29