2

I have a form which is for sending mails.It contain fields such as to_name,subject,message and attachment button.I will create a file input field on clicking the button with class .file_add_btn.

//click event for add files
$(".file_add_btn").click(function(){
    if($("#file_div").html() == '')
    {
       $("#file_div").append('<div class="file_btn_div" id="file_btn_div_first"><input type="file" class="btn_browse" name="file_uploads[]">'+
       '<input type="button" class="del_file" value="X"></div>'); 
    }
    else
    {
        if($(document).find('.btn_browse:last').get(0).files.length !==0)
        {
            $("#file_div").append('<div class="file_btn_div"><input type="file" class="btn_browse" name="file_uploads[]">'+
            '<input type="button" class="del_file" value="X"></div>');
        }
    }

});

I write the following function to include file inputs into formData.

$.fn.serializefiles = function() {
    var obj = $(this);

    var form_data = new FormData(this[0]);
    $.each($(obj).find('.btn_browse'), function(i, tag) {
        $.each(tag.files, function(i, file) {
             console.log(tag.name+' '+file.name)//this is printing in console
                form_data.append(tag.name, file);
        });
    });
    var params = $(obj).serializeArray();
    $.each(params, function (i, val) {
            console.log(val.name+'<br/>');
            console.log(val.value+'<br/>');
            **//here file names are not coming.All other elements are coming.They are not adding to form_data object**
            form_data.append(val.name, val.value);
    });
    return form_data;
}; 

My ajax call is like the following:

$.ajax({
    type: "POST", 
    url: 'process.php',
    data: $("#compose_message").serializefiles() ,//formID=#compose_message
    asyn: true,
    cache: false,
    processData: false,
    contentType: false,
    success:function()
          ....

I am not able to append the inputs into the form_data object.In console,I see [object FormData] inside the POST on button click.

Amaan Iqbal
  • 761
  • 2
  • 9
  • 25
Techy
  • 2,626
  • 7
  • 41
  • 88
  • I'm confused as to why you need this `serializefiles` function, when you should be able to simply do `data: new FormData($("#compose_message")[0])`? – Mikey Jun 01 '16 at 11:20
  • If we do `data: new FormData($("#compose_message")[0])`,how can I append the multiple file inputs and other formdatas@Mikey – Techy Jun 01 '16 at 11:22
  • @Mikey I have used `console.log(JSON.stringify(new FormData($("#compose_message")[0])));`,this is giving me empty value `{}` in console. – Techy Jun 01 '16 at 11:26

3 Answers3

3

Edit: My initial comment above was correct. You don't need to do anything fancy except pass the form object into FormData constructor as shown in my example below.

console.log(JSON.stringify(formData)); will never show the values of the FormData. However, if you look in your browser's network tab, the request that gets sent will show the values being passed.

If you want to check the data before it is being passed, you could use this answer.

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-2.1.4.js"></script>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <title>JS Bin</title>
    <style>
        input {
            float: left;
            clear: left;
        }
    </style>
</head>
<body>
    <form method="post" enctype="multipart/form-data">
        <input type="text" name="text" value="text">
        <input type="hidden" name="hidden" value="hidden">
        <input type="file" name="file_uploads[]" value="">
        <input type="file" name="file_uploads[]" value="">
        <input type="file" name="file_uploads[]" value="">
        <input type="button" value="Add">
        <input type="submit" value="Submit">
    </form>
    <script>
    $(function () {
        $('form').on('submit', function (e) {
            e.preventDefault();
            var formData = new FormData(this);
            console.log(JSON.stringify(formData)); // will always be {}

            $.ajax({ url: '404', type: 'post', data: formData, processData: false, contentType: false });
        });

        $('[type=button]').on('click', function () {
            $(this).before('<input type="file" name="file_uploads[]" value="">');
        });
    });
    </script>
</body>
</html>
Community
  • 1
  • 1
Mikey
  • 6,728
  • 4
  • 22
  • 45
  • I have checked the result using `console.log(JSON.stringify(formData));` after copying your code,but it gives me `{}`.What can be the reason my bro – Techy Jun 01 '16 at 11:43
  • That's because you can't print the contents of `FormData` that way. I edited my answer with a quick example and tested it locally. – Mikey Jun 01 '16 at 12:24
  • I have used this code but in my `process.php`,its giving me `Uncaught exception 'RuntimeException' with message 'Invalid parameters.` since I used `if ( !isset($_FILES['file_uploads']['error']) || is_array($_FILES['file_uploads']['error']) ) { throw new RuntimeException('Invalid parameters.'); }` – Techy Jun 01 '16 at 12:34
  • If you examine your `$_FILES` array, using `print_r`, it should be similar to [this](http://php.net/manual/en/features.file-upload.multiple.php#53240) where every value is an array. When you use this AJAX approach of submitting files, I think there will always be arrays. You need to loop through each file and do the necessary checking (and by minimum using [is_uploaded_file()](http://php.net/manual/en/function.is-uploaded-file.php)). – Mikey Jun 01 '16 at 12:46
  • The `$_FILES` is empty array for me:( – Techy Jun 01 '16 at 12:55
  • I am using same code with a sample script and it works :/ I got some time to [chat](http://chat.stackoverflow.com/) if you want. – Mikey Jun 01 '16 at 13:07
  • If you can I can give my teamviewer..so that you can check.plz – Techy Jun 01 '16 at 13:08
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/113532/discussion-between-mikey-and-techy). – Mikey Jun 01 '16 at 13:12
1

specify exact data for formdata

var formData = new FormData();
formData.append('section', 'general');
formData.append('action', 'previewImg');
// Main magic with files here
formData.append('image', $('input[type=file]')[0].files[0]); 

Ajax request with jquery will looks like this:

$.ajax({
    url: 'Your url here',
    data: formData,
    // THIS MUST BE DONE FOR FILE UPLOADING
    contentType: false,
    processData: false,
    // ... Other options like success and etc
})
  • Should I need to append each form elements seperately.I am doing the same thing inside my function – Techy Jun 01 '16 at 11:24
  • I have used `formData.append('section', 'general');` for testing.Then also `console.log(JSON.stringify(new FormData($("#compose_message")[0])));` gives me `{}` string.I think `formData` is not been appended with the values – Techy Jun 01 '16 at 11:34
0

try this

  var form = $("form")[0]; // You need to use standard javascript object here
    var formData = new FormData(form);
    formData.append('section', 'general');
    formData.append('action', 'previewImg');
    // Main magic with files here
    formData.append('image', $('input[type=file]')[0].files[0]);
Basharmal
  • 1,313
  • 10
  • 30