javascripthtmlbootstrap-4bootstrap-file-input

How to clear any other previously selected file from bootstrap 4 input file


I have a form with an input file that I implemented with Bootstrap 4. This input file does not work out of the box, since it needs Javascript to work as intended: the user clicks on the "browse files" button, a window opens, the user selects their file, clicks on open/select and the file name is finally displayed on the input field.

<form id="my_form" name="my_form" method="post" action="/action" enctype="multipart/form-data">
   <div class="input-group" id="div_input">
      <div class="custom-file">
         <input type="file" accept=".pdf" class="custom-file-input" id="myInputGroup" name="userfile" aria-describedby="btnUpload">
         <label class="custom-file-label" for="myInputGroup" data-browse="Browse files" id="input_label_identificacion">Select a file</label>
      </div>
      <div class="input-group-append" id="divBtnUpload">
         <button class="btn btn-outline-info" type="submit" value="submitFile" id="btnUpload" title="Upload your file" disabled>Upload</button>
      </div>
   </div>
</form>

Here is the javascript file to make it work:

$('#myInputGroup').on('change',function(e){
    {{--//get the file name--}}
    var fileName = e.target.files[0].name;
    {{--replace the "Choose a file" label--}}
    $(this).next('.custom-file-label').html(fileName);
    
    enableUploadButton(inputIdentificacionId,btnIdentificacionId);
    
    document.getElementById('my_form').addEventListener('submit', function(evt) {
        evt.preventDefault();
        $('#'+btnIdentificacionId).prop("disabled",true);
        upload(this.action,'userfile',e.target.files[0]);
    }, {once: true});
});

I have implemented a javascript button "upload file" where the user clicks on it and the file is uploaded. So far so good.

The problem I see is that, if a user browses a file, selects it, and then if the user clicks again on the "browse files" button, the last selected file is sent twice or at least the number of times the user selected a file.

So I thought of clearing the input file when the user is browsing a file. This is what I've tried so far in the javascript:

$('#myInputGroup').on('click',function (e){
   document.getElementById('inputGroup_solicitud').value= null;
   //console.log('User is browsing ...');
   //console.log(this.files);
   inputGroup_solicitud.value='';//My attempt to clear the input but it doesn't work
   e.target.files=null;
   this.files=null;
});

However, the issue is still happening. If a user clicks again and selects any file, the upload function sends the last selected file twice to the server or at least the number of times the user clicked on the "browse button" and selected a file.

Note as for possible duplicate question This answer does not help me solve my question, since the issue actually is that an 'addEventListener()' is being added every time the user browses a file. This detail is not explained in that other question.

How do I clear the input file in order to prevent that multiple files are sent?


Solution

  • You're adding a new event listener every time the change event fires. Therefore by the time the user clicks submit, there are multiple event listeners that are fired: one for every time they browsed a file. Each of these uploads the file, hence causing your problem.

    To fix it, you need to move the block of code:

    document.getElementById('my_form').addEventListener('submit' 
    ...
    

    outside of the enclosing change hander. You'll need a var outside both scopes to share the file between the two event handlers. Something like this (untested!):

    // Both event handler can access this var
    var file;
    
    $('#myInputGroup').on('change',function(e){
        var fileName = e.target.files[0].name;
        $(this).next('.custom-file-label').html(fileName);
        enableUploadButton(inputIdentificacionId,btnIdentificacionId);
        // Store the file to be uploaded
        file = e.target.files[0];
    });
        
    document.getElementById('my_form').addEventListener('submit', function(evt) {
        evt.preventDefault();
        $('#'+btnIdentificacionId).prop("disabled",true);
        // Retrieve and upload your file
        upload(this.action,'userfile',file);
    }, {once: true});