3

I am here to know that How to add/upload/choose multiple files from one input tag that is multiple but after selecting again all previous selection were removed or override. what I want is.

  1. selection of multiple files. (will make preview, ok this is done).
  2. user can remove from selection from preview.
  3. add more files/image to current selection
AWE
  • 213
  • 1
  • 4
  • 12

1 Answers1

13

You can hide the input[type=file] and provide an UI that interacts with the input in order to select new files and manage separately a list of files.

So you can:

  1. add a hidden input <input id="myInput" type="file" multiple style="display:none" />

  2. Provide a good looking UI with a button that calls the myInput.click() in order to open the prompt

  3. subscribe to input change event and get the myInput.files and store them in an array or collection

  4. to upload all files via AJAX just create a FormData and append all the files then pass FormData instance to the ajax call (eg: $ajax({...data: formData...})).

EDITED:

Plnkr link

Sample Behavior:

  • Pressing "+ Add Files" button will add new files to the list.
  • Clicking a file in the list will remove the file
  • Pressing "Send Files" button will send the files to the corresponding URL

Sample HTML:

<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8" />
    <title></title>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="script.js"></script>
  </head>

  <body>
    <input id="myInput" type="file" multiple style="display:none" />
    
    <button id="myButton" type="button" style="border-radius: 5px; background-color: #fff; color: green;">+ Add Files</button>
    <button id="mySubmitButton" type="button" style="border-radius: 5px; background-color: #fff; color: green;">Send Files</button>
    
    <div id="myFiles"></div>
  </body>

</html>

Sample Script:

$(function(){
  let inputFile = $('#myInput');
  let button = $('#myButton');
  let buttonSubmit = $('#mySubmitButton');
  let filesContainer = $('#myFiles');
  let files = [];
  
  inputFile.change(function() {
    let newFiles = []; 
    for(let index = 0; index < inputFile[0].files.length; index++) {
      let file = inputFile[0].files[index];
      newFiles.push(file);
      files.push(file);
    }
    
    newFiles.forEach(file => {
      let fileElement = $(`<p>${file.name}</p>`);
      fileElement.data('fileData', file);
      filesContainer.append(fileElement);
      
      fileElement.click(function(event) {
        let fileElement = $(event.target);
        let indexToRemove = files.indexOf(fileElement.data('fileData'));
        fileElement.remove();
        files.splice(indexToRemove, 1);
      });
    });
  });
  
  button.click(function() {
    inputFile.click();
  });
  
  buttonSubmit.click(function() {
    let formData = new FormData();
    
    files.forEach(file => {
      /* here I just put file as file[] so now in submitting it will send all 
      files */
      formData.append('file[]', file);
    });
    
    console.log('Sending...');
    
    $.ajax({
      url: 'https://this_is_the_url_to_upload_to',
      data: formData,
      type: 'POST',
      success: function(data) { console.log('SUCCESS !!!'); },
      error: function(data) { console.log('ERROR !!!'); },
      cache: false,
      processData: false,
      contentType: false
    });
  });
});
Sachin Sarola
  • 993
  • 1
  • 9
  • 26
andreim
  • 3,365
  • 23
  • 21
  • 3) subscribe to input change event and get the myInput.files and store them in an array or collection? I am worried about it. how we can store reference of files in array? 4) to upload all files via AJAX just create a FormData and append all the files then pass FormData instance to the ajax call ? – AWE Apr 12 '17 at 06:18
  • what is let instead of var? – AWE Apr 12 '17 at 08:54
  • Check [this answer](http://stackoverflow.com/questions/762011/whats-the-difference-between-using-let-and-var-to-declare-a-variable) which describes well this subject. Also consider using const and let instead of var. – andreim Apr 12 '17 at 09:09
  • In php I am printing $_FILES here receiving only once file? – AWE Apr 12 '17 at 09:24
  • Handling of multi-part data depends on the server side implementation. If you are using PHP maybe the data needs to be sent from client like - `formData.append('file[]', file);` - file[] instead of file. And then we would expect to have $_FILES['file']. I'm not a PHP knowledgeable person but this link might help with the PHP issue - [LINK](http://stackoverflow.com/questions/12989442/uploading-multiple-files-using-formdata) – andreim Apr 12 '17 at 09:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/141532/discussion-between-awe-and-andrei-macarie). – AWE Apr 12 '17 at 10:19
  • can we make X instead of clicking on images to remove the file? – AWE Apr 12 '17 at 10:33
  • @andreim Hey, thanks for this solution! Do you know of any lightweight plugin that might do this (I have looked at JQuery-File-Upload but it seems like it has a lot of dependencies and requires submitting via AJAX)? Also, if I want to simply attach the files to my form, I suppose I would do something like: `new FormData($("form")).append("file",file);` (assuming I had an input element named "file")? – theyuv Mar 29 '18 at 15:07
  • @andreim I have made changes in your code because in submitting it will show only last added file. – Sachin Sarola Jul 27 '20 at 07:35
  • Drag and drop will not work if we do like this – Glitson George Mar 10 '22 at 15:31