hex494D49
hex494D49

Reputation: 9235

Uploading multiple forms using FormData and a single XMLHttpRequest with Javascript

Let's say I have two forms of the same structure but having different values at the end. I'd like to submit both of them using FormData and a single XMLHttpRequest request. I was trying to add another FormData object or an additional array but the result is an empty response so far.

HTML

<!-- first form -->
<form enctype="multipart/form-data" method="post" action="/" >
  <input type="hidden" name="entity" value="1" />
  <input type="text" name="name" value="" />
  <input type="text" name="email" value="" />
  <input type="password" name="password" value="" />
  <input type="file" name="file[]" multiple />
</form>

<!-- second form -->
<form enctype="multipart/form-data" method="post" action="/" >
  <input type="hidden" name="entity" value="1" />
  <input type="text" name="name" value="" />
  <input type="text" name="email" value="" />
  <input type="password" name="password" value="" />
  <input type="file" name="file[]" multiple />
</form>

JavaScript

var a = new FormData(); // using additional FormData object
var b = [];             // using an array
for(var i = 0; i < document.forms.length; i++){
  var form = document.forms[i];
  var data = new FormData(form);
  if(typeof form['file'] !== 'undefined'){
    for(var j=0; j<form['file'].files.length; j++){
      data.append('file[]', form['file'].files[j]);
    }
  }
  a.append(i, JSON.stringify(data)); // or a.append(i, data);
  b[i] = JSON.stringify(data);       // or b[i] = data;

}
var xhr = new XMLHttpRequest();
var url = "ajax.php";
xhr.open("POST", url, true);
xhr.onreadystatechange = function (){
  if(xhr.readyState == 4 && xhr.status == 200){
    console.log(xhr.responseText);
  }
}
xhr.send(a); // or xhr.send(b); 

PHP

echo json_encode(array_merge($_GET, $_POST, $_FILES));
// or
print_r(array_merge($_GET, $_POST, $_FILES));

Upvotes: 3

Views: 8090

Answers (1)

Dekel
Dekel

Reputation: 62556

You have several problems there. One of the problems is that the name of your input is file[] and not file, so you need to use that name. The other problem is that you can't use JSON.stringify if you want to post files to the server.

Check the change I did to your code, it will do what you are looking for:

var a = new FormData(); // using additional FormData object
var b = [];             // using an array
for(var i = 0; i < document.forms.length; i++){
    var form = document.forms[i];
    var data = new FormData(form);
    var formValues = data.entries()
    while (!(ent = formValues.next()).done) {

        // Note the change here 
        a.append(`${ent.value[0]}[]`, ent.value[1])
    }
}
// here a will include all the data from all of your forms.
<!-- first form -->
<form enctype="multipart/form-data" method="post" action="/" >
  <input type="hidden" name="entity" value="1" />
  <input type="text" name="name" value="" />
  <input type="text" name="email" value="" />
  <input type="password" name="password" value="" />
  <input type="file" name="file[]" multiple />
</form>

<!-- second form -->
<form enctype="multipart/form-data" method="post" action="/" >
  <input type="hidden" name="entity" value="1" />
  <input type="text" name="name" value="" />
  <input type="text" name="email" value="" />
  <input type="password" name="password" value="" />
  <input type="file" name="file[]" multiple />
</form>

Upvotes: 5

Related Questions