0

I created a on submit function that grabs different data along with images, if the user has uploaded them and ties the images into a FormData type object. This is than sent along with other data to the server to upload. My issue is that, I seem to be having trouble getting the images to the server along with other variables. All I get on success a blank response.

Here is what I am doing:

ElevationColorsForm.prototype.submit = function()
{
    // DEFUALT SET FORMDATA TO FALSE
    var formdata = false;
    // MAKE SURE BROWSER SUPPORTS FORM DATA
    if (window.FormData) {
        formdata = new FormData();
    }
    /************ DATA IS SENT TO SERVER TO BE STORED ON SAVE CHANGES *****************/
    var color_name = '';//<!-- CONTAIN NAME OF COLOR SET IN INPUT FIELD
    var color_file = '';//<!-- CONTAIN THE IMAGE TO BE UPLOADED // MOVED OVER TO THE formdata
    var color_type = [];//<!-- EITHER new_color OR current_color

    color_name = $(".color-item-input").map(function() 
    {       
        return this.value 

    }).get().join(", ");
    color_file = $(".color-item-file").each(function()
    {

        if(this.files.length > 0)
        {
            if (!!this.files[0].type.match(/image.*/)) {

                var file =  this.files[0];
                var reader;

                if ( window.FileReader ) {
                  reader = new FileReader();
                  reader.readAsDataURL(file);
                }
                if (formdata) {
                    formdata.append("images[]", file);
                }

                return file;    
            } 
            else
            {
                formdata.append("images[]", 'none');
                return 'false';
            }
        }
        else
        {
            formdata.append("images[]", 'none');
            return 'false'; 
        }

    }).get();
    $(".color-item").each(function()
    {           
        if($(this).hasClass('current-color'))
        {
            color_type.push('current-color');
        }
        else if($(this).hasClass('new_color'))
        {
            color_type.push('new-color');
        }

    });
    var RestrictionSelectActive = $(".restriction_active_ability option:selected").each(function()
    {           
        return this.value 

    }).get();

    var thisOne = this.Elevation.data.ifpe_id; // <!-- ELEVATION ID
    $.ajax({
        url: "actions/save_elevation_colors.php",
        type: "post",
        data:
        {
            'formData' : formdata,
            'elevation_id' : thisOne
        },
        processData: false,
        contentType: false,
        success: function(data){
            console.log(data);
            $(".message_box").text("Changes made!");
            $(".message_box").fadeIn(); 
            setTimeout(function(){
                $(".message_box").fadeOut();
                $(".message_box").empty();  
            },2000);
        },
        error:function(){
            alert("failure");
        }
    });
}

Here is my data response: {"status":"ok","code":1,"original_request":[]}

My server side is creating an array and storing all the the $_POST within the original_request and than json_encoding for retrieval.

suggestions or thoughts?

David Biga
  • 177
  • 13
  • WTH is that `FileReader` supposed to do there? – Bergi Jun 06 '14 at 01:45
  • @Bergi the more I look at it the more I really don't know anymore. Can I decode it and use that to send it over and recode it in PHP? – David Biga Jun 06 '14 at 01:54
  • No reason to do that, `FormData` does this for you. And I'm sure that the browsers that don't support `FormData` don't support `FileReader` either. – Bergi Jun 06 '14 at 02:03

1 Answers1

2

You cannot just add a FormData object as a property to the data object. You can only send one FormData object alone, which will get encoded appropriately. If you pass a key-value object, jQuery will try to www-form-urlencode that. See also How to send FormData objects with Ajax-requests in jQuery?.

ElevationColorsForm.prototype.submit = function() {
    if (!window.FormData) {
        alert("Sorry, your browser does not support uploading files with Ajax.");
        throw new Error("no FormData support");
    }

    function getValue() { return this.value; }

    var formdata = new FormData();

    var color_name = $(".color-item-input").map(getValue).get().join(", ");
    var RestrictionSelectActive = $(".restriction_active_ability option:selected").map(getValue).get();
    var color_type = $(".color-item").map(function() {           
        if ($(this).hasClass('current-color'))
            return 'current-color';
        if ($(this).hasClass('new_color'))
            return 'new-color';
        return '';
    }).get();

    $(".color-item-file").each(function() {
        if(this.files.length > 0 && /image.*/.test(this.files[0].type)) {
             formdata.append("images[]", this.files[0]);
        } else {
            formdata.append("images[]", 'none');
        }
    });

    formdata.append('elevation_id', this.Elevation.data.ifpe_id);
//  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    $.ajax({
        url: "actions/save_elevation_colors.php",
        type: "post",
        data: formdata,
//            ^^^^^^^^
        processData: false,
        contentType: false
    }).then(function(data){
        console.log(data);
        $(".message_box").text("Changes made!");
        $(".message_box").fadeIn(); 
        setTimeout(function(){
            $(".message_box").fadeOut();
            $(".message_box").empty();  
        },2000);
    }, function(){
        alert("failure");
    });
}
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • what is my solution? I need more data sent at the same time. – David Biga Jun 06 '14 at 01:55
  • Just append all of the data to your `formdata` object – Bergi Jun 06 '14 at 02:04
  • So whenever I need to send data just attach it to the `formdata` – David Biga Jun 06 '14 at 02:09
  • Out of curiosity do you know why we have to set `processData` and `contentType` to false? – David Biga Jun 06 '14 at 02:10
  • `processData` is set to `false` because the `data` is some kind of object, and jQuery would try to enumerate its properties and www-form-urlencode them as URL parameters. It needs to directly pass the `formdata` into the XHR `.send()` method. `contentType` is set to `false` [because otherwise jQuery would manually set it](http://stackoverflow.com/a/5976031/1048572), and that would break the request. – Bergi Jun 06 '14 at 02:16