43

How can I post file and input string data with FormData()? For instance, I have many other hidden input data that I need them to be sent to the server,

html,

<form action="image.php" method="post" enctype="multipart/form-data">
<input type="file" name="file[]" multiple="" />
<input type="hidden" name="page_id" value="<?php echo $page_id;?>"/>
<input type="hidden" name="category_id" value="<?php echo $item_category->category_id;?>"/>
<input type="hidden" name="method" value="upload"/>
<input type="hidden" name="required[category_id]" value="Category ID"/>
</form>

With this code below I only manage to send the file data but not the hidden input data.

jquery,

// HTML5 form data object.
var fd = new FormData();

var file_data = object.get(0).files[i];
var other_data = $('form').serialize(); // page_id=&category_id=15&method=upload&required%5Bcategory_id%5D=Category+ID

fd.append("file", file_data);

$.ajax({
    url: 'add.php',
    data: fd,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function(data){
        alert(data);
    }
});

server.php

print_r($_FILES);
print_r($_POST);

result,

Array
(
    [file] => Array
        (
            [name] => xxx.doc
            [type] => application/msword
            [tmp_name] => C:\wamp\tmp\php7C24.tmp
            [error] => 0
            [size] => 11776
        )

)

I would like to get this as my result though,

Array
(
    [file] => Array
        (
            [name] => xxx.doc
            [type] => application/msword
            [tmp_name] => C:\wamp\tmp\php7C24.tmp
            [error] => 0
            [size] => 11776
        )

)

Array
(
    [page_id] => 1000
    [category_id] => 12
    [method] => upload
    ...
)

Is it possible?

Run
  • 54,938
  • 169
  • 450
  • 748

11 Answers11

96
var fd = new FormData();
var file_data = $('input[type="file"]')[0].files; // for multiple files
for(var i = 0;i<file_data.length;i++){
    fd.append("file_"+i, file_data[i]);
}
var other_data = $('form').serializeArray();
$.each(other_data,function(key,input){
    fd.append(input.name,input.value);
});
$.ajax({
    url: 'test.php',
    data: fd,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function(data){
        console.log(data);
    }
});

Added a for loop and changed .serialize() to .serializeArray() for object reference in a .each() to append to the FormData.

Mike
  • 14,010
  • 29
  • 101
  • 161
manta
  • 1,663
  • 12
  • 12
  • 4
    how would you get each value in php can you share that please ?? – Uzumaki Naruto Sep 29 '14 at 14:23
  • For Multiple File browse Button : http://stackoverflow.com/questions/21060247/send-formdata-and-string-data-together-through-jquery-ajax/29774331#29774331 – Lakhan Apr 21 '15 at 13:58
  • Found that the formdata (fd) cannot be included with other information. i.e. data:( state:'state', fd: fd ), Using the above example, no data will not transfer through ajax. I created a separate php file to accept the upload and it works great when fd (formdata) is sent by itself. – nwolybug Jun 13 '16 at 17:29
  • Thanks it works but you should try some more less code & i did same thing with less code – Adeel Ahmed Baloch Mar 29 '22 at 05:05
25

well, as an easier alternative and shorter, you could do this too!!

var fd = new FormData();

var file_data = object.get(0).files[i];
var other_data = $('form').serialize(); //page_id=&category_id=15&method=upload&required%5Bcategory_id%5D=Category+ID

fd.append("file", file_data);

$.ajax({
    url: 'add.php?'+ other_data,  //<== just add it to the end of url ***
    data: fd,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function(data){
        alert(data);
    }
});
azerafati
  • 18,215
  • 7
  • 67
  • 72
  • 2
    Note that the other_data can be accessed via $_GET. Great answer. – AndyOS Nov 18 '15 at 01:12
  • 1
    why does the accepted answer have so much upvotes? it is wrong and is not working - thank you for your hint - it's great – Okizb Oct 24 '20 at 17:57
9

I always use this.It send form data using ajax

$(document).on("submit", "form", function(event)
{
    event.preventDefault();

    var url=$(this).attr("action");
    $.ajax({
        url: url,
        type: 'POST',            
        data: new FormData(this),
        processData: false,
        contentType: false,
        success: function (data, status)
        {

        }
    });
});
Shaiful Islam
  • 7,034
  • 12
  • 38
  • 58
6

I try to contribute my code collaboration with my friend . modification from this forum.

$('#upload').on('click', function() {
            var fd = new FormData();
              var c=0;
              var file_data,arr;
              $('input[type="file"]').each(function(){
                  file_data = $('input[type="file"]')[c].files; // get multiple files from input file
                  console.log(file_data);
               for(var i = 0;i<file_data.length;i++){
                   fd.append('arr[]', file_data[i]); // we can put more than 1 image file
               }
              c++;
           }); 

               $.ajax({
                   url: 'test.php',
                   data: fd,
                   contentType: false,
                   processData: false,
                   type: 'POST',
                   success: function(data){
                       console.log(data);
                   }
               });
           });

this my html file

<form name="form" id="form" method="post" enctype="multipart/form-data">
<input type="file" name="file[]"multiple>
<input type="button" name="submit" value="upload" id="upload">

this php code file

<?php 
$count = count($_FILES['arr']['name']); // arr from fd.append('arr[]')
var_dump($count);
echo $count;
var_dump($_FILES['arr']);

if ( $count == 0 ) {
   echo 'Error: ' . $_FILES['arr']['error'][0] . '<br>';
}
else {
    $i = 0;
    for ($i = 0; $i < $count; $i++) { 
        move_uploaded_file($_FILES['arr']['tmp_name'][$i], 'uploads/' . $_FILES['arr']['name'][$i]);
    }

}
?>

I hope people with same problem , can fast solve this problem. i got headache because multiple upload image.

neophyte
  • 6,540
  • 2
  • 28
  • 43
Herry Karmito
  • 61
  • 1
  • 1
3

From what I understand you would like to send the images and the values of the inputs together. This code works well for me, I hope it helps someone in the future.

<form id="my-form" method="post" enctype="multipart/form-data">
<input type="file" name="file[]" multiple="" />
<input type="hidden" name="page_id" value="<?php echo $page_id;?>"/>
<input type="hidden" name="category_id" value="<?php echo $item_category->category_id;?>"/>
<input type="hidden" name="method" value="upload"/>
<input type="hidden" name="required[category_id]" value="Category ID"/>
</form>

-

jQuery.ajax({
url: 'post.php',
data: new FormData($('#my-form')[0]),
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function(data){
    console.log(data);
}});

Take a look at my short code for ajax multiple upload with preview.

https://santanamic.github.io/ajax-multiple-upload/

2

You can try this:

var fd = new FormData();
var data = [];           //<---------------declare array here
var file_data = object.get(0).files[i];
var other_data = $('form').serialize();

data.push(file_data);  //<----------------push the data here
data.push(other_data); //<----------------and this data too

fd.append("file", data);  //<---------then append this data
Jai
  • 74,255
  • 12
  • 74
  • 103
  • thanks but I get this, `Array ( ) Array ( [file] => [object File],page_id=&category_id=15&system_id=53&method=upload&required%5Bcategory_id%5D=Category+ID )` – Run Jan 11 '14 at 08:58
1

For Multiple file input : Try this code :

 <form name="form" id="form" method="post" enctype="multipart/form-data">
    <input type="file" name="file[]">
    <input type="file" name="file[]" >
    <input type="text" name="name" id="name">
    <input type="text" name="name1" id="name1">
    <input type="button" name="submit" value="upload" id="upload">
 </form>


 $('#upload').on('click', function() {
  var fd = new FormData();
    var c=0;
    var file_data;
    $('input[type="file"]').each(function(){
        file_data = $('input[type="file"]')[c].files; // for multiple files

     for(var i = 0;i<file_data.length;i++){
         fd.append("file_"+c, file_data[i]);
     }
    c++;
 }); 
     var other_data = $('form').serializeArray();
     $.each(other_data,function(key,input){
         fd.append(input.name,input.value);
     });
     $.ajax({
         url: 'work.php',
         data: fd,
         contentType: false,
         processData: false,
         type: 'POST',
         success: function(data){
             console.log(data);
         }
     });
 });
NavidIvanian
  • 347
  • 5
  • 15
Lakhan
  • 12,328
  • 3
  • 19
  • 28
1

For multiple files in ajax try this

        var url = "your_url";
        var data = $('#form').serialize();
        var form_data = new FormData(); 
        //get the length of file inputs   
        var length = $('input[type="file"]').length; 

        for(var i = 0;i<length;i++){
           file_data = $('input[type="file"]')[i].files;

            form_data.append("file_"+i, file_data[0]);
        }

            // for other data
            form_data.append("data",data);


        $.ajax({
                url: url,
                type: "POST",
                data: form_data,
                cache: false,
                contentType: false, //important
                processData: false, //important
                success: function (data) {
                  //do something
                }
        })

In php

        parse_str($_POST['data'], $_POST); 
        for($i=0;$i<count($_FILES);$i++){
              if(isset($_FILES['file_'.$i])){
                   $file = $_FILES['file_'.$i];
                   $file_name = $file['name'];
                   $file_type = $file ['type'];
                   $file_size = $file ['size'];
                   $file_path = $file ['tmp_name'];
              }
        }
Ananya96
  • 61
  • 4
1
 var fd = new FormData();
    //Get Form Values
    var other_data = $('#form1').serializeArray();
    $.each(other_data, function (key, input) {
     fd.append(input.name, input.value);
     });

     //Get File Value
      var $file = jq("#photoUpload").get(0);
      if ($file.files.length > 0) {
      for (var i = 0; i < $file.files.length; i++) {
      fd.append('Photograph' + i, $file.files[i]);
       }
     }
$.ajax({
    url: 'test.php',
    data: fd,
    contentType: false,
    processData: false,
    type: 'POST',
    success: function(data){
        console.log(data);
    }
});
0

I found that, if somehow(like your ModelState is false on server.) and page post again to server then it was taking old value to the server. So i found that solution for that.

   var data = new FormData();
   $.each($form.serializeArray(), function (key, input) {
        if (data.has(input.name)) {
            data.set(input.name, input.value);
        } else {
            data.append(input.name, input.value);
        }
    });
Shailendra Kumar
  • 138
  • 2
  • 12
0

i solved my problem using below logic

var ObjformData   = new FormData(document.getElementById('Form1'));  // form 1 data
var ArrayformData = $('#Form2').serializeArray();  // form 2 data

// merging form 2 data into form1 data 
$.each(formDataObj2, function (key, input)
    {
        if (formDataObj1.has(input.name)) {
            formDataObj1.set(input.name, input.value);
        } else {
            formDataObj1.append(input.name, input.value);
        }
 });


   // file data output
   console.log(ObjformData);

I did this thing for image uploading using ajax. in my case from1 have multiple images & form2 have just normal user inputs just simple input more then 30 fields I am sured it will be helpful for u Happy Coding :)

Adeel Ahmed Baloch
  • 672
  • 2
  • 7
  • 15