Search code examples
javascriptajaxhtmlajaxform

collect multiple inputs file to append to FormData


Suppose I have the following form.

<form id="testForm">
  <input type="file" name="uploads[]"><br/>
  <input type="file" name="uploads[]"><br/>
  <input type="file" name="uploads[]"><br/>
  <input type="submit">
</form>

And this is part of the submit code which tries to collect files to append to FormData, but I don't know how to do it properly.

var formData = new FormData();

var fileList = $("input[name='uploads[]']");
for(var x = 0; x < fileList.length; x++) {
  formData.append('file'+x, ???);
  console.log('appended a file');
}

var request = new XMLHttpRequest();
request.open('POST', '/upload');
request.send(formData);

request.onload = function(e) {
  console.log('Request Status', request.status);
};

This is the server code.

app.post('/upload', function(req, res) {
  var form = new formidable.IncomingForm();
  form.parse(req, function(err, fields, files) {
    console.log('handling form upload - fields', fields);
    console.log('handling form upload - files', files);
  });
  res.send('Thank you');
});

If it works, I expect to see output and files saved in /tmp.


Solution

  • You don't have to collect fields since you can put the form itself into FormData object:

    var form = document.getElementById('testForm');
    
    form.addEventListener('submit', function(e) {
    
      e.preventDefault();
    
      var request = new XMLHttpRequest();
      request.open('POST', '/upload');
    
      request.onload = function(e) {
        console.log('Request Status', request.status);
      };
    
      var formData = new FormData(form);
      request.send(formData);
    });
    

    UPDATE

    If you need to upload several files, you might use multiple attribute on the input instead of several inputs:

    <form id="testForm">
      <input type="file" name="upload" multiple>
      <input type="submit">
    </form>