abaracedo
abaracedo

Reputation: 1454

Put FormData object into an array to upload files from different input files

i have a form like this one:

<form>

    <div class="characteristicData" id="1">
        <textarea></textarea>
        <input type="file" name="filelist-1" />
    </div>

    <div class="characteristicData" id="2">
            <textarea></textarea>
            <input type="file" name="filelist-2" />
    </div>

    <input type="button" class="send" value="Send" />

</form>

This form contains three divs to distinguish the data that is needed to send it correctly to the server and set in a DB the correct values for the belonging id.

The data that i wanted to get on the server for $_POST and $_FILES was something like this:

$_POST

Array
(
    [characteristic] => Array
    (
        [element_0] => Array
        (
            [id_characteristic] => 1
            [items] => 0001,0002,0003
        )

        [element_1] => Array
        (
            [id_characteristic] => ="2"
            [items] => 0001,0002,0003
        )

     )

 )

$_FILES

Array
(
    [characteristic] => Array
    (
        [element_0] => Array
        (
            [name] => items.csv
            [type] => application/vnd.ms-excel
            [tmp_name] => tmp/php44DF.tmp
            [error] => 0
            [size] => 8
        )
        [element_1] => Array
        (
            [name] => items.csv
            [type] => application/vnd.ms-excel
            [tmp_name] => tmp/php44DF.tmp
            [error] => 0
            [size] => 8
        )
    )
)

So, my option was trying to create an object containing keys and each key containing the FormData object. At the end, my jQuery is this:

$(function() {

    $(".send").click(function() {

        var formdata = new FormData(),
            $this,
            fileDOM = $("input[type='file']")[0];

        $(".characteristicData").each(function(i, v) {

            $this = $(this);
            fileDOM = $this.find("input[type='file']")[0];

            formdata.append("characteristic[element_"+i+"][id_characteristic]", $this.attr("id"));
            formdata.append("characteristic[element_"+i+"][items]", $this.find("textarea").val());

            if ( $this.find("input[type='file']").val() ) {
                formdata.append("characteristic[element_"+i+"][file]", fileDOM.files[0], fileDOM.files[0].name);
            }

        });

        $.ajax({
            url: "upload.php",
            type: "POST",
            data: formdata,
            processData: false,
            contentType: false
        });

    });

});

That code works fine and when i print the $_POST and $_FILES variables the result is what i expected, but not for the $_FILES. What i get from files is:

Array
(
    [characteristic] => Array
    (
        [name] => Array
        (
            [element_0] => Array
            (
                [file] => items.csv
            )

            [element_1] => Array
            (
                [file] => items.csv
            )
        )

        [type] => Array
        (
            [element_0] => Array
            (
                [file] => application/vnd.ms-excel
            )

            [element_1] => Array
            (
                [file] => application/vnd.ms-excel
            )
        )

        [tmp_name] => Array
        (
            [element_0] => Array
            (
                [file] => E:\wamp\tmp\php44DF.tmp
            )

            [element_1] => Array
            (
                [file] => E:\wamp\tmp\php44E0.tmp
            )
        )

        [error] => Array
        (
            [element_0] => Array
            (
                [file] => 0
            )

            [element_1] => Array
            (
                [file] => 0
            )

        )

        [size] => Array
        (
            [element_0] => Array
            (
                [file] => 8
            )

            [element_1] => Array
            (
                [file] => 8
            )
        )
    )
)

Is there any way to get the result that i expected to get?

Upvotes: 1

Views: 2102

Answers (1)

abaracedo
abaracedo

Reputation: 1454

After days without looking for a solution to my problem, today I decided to find it and I did it.

First I tried to put the whole data from each div into an array and then put that array in the formdata, the problem was that on the server I got an [object file] and I couldn't get anything from it. The $_FILES array was empty, so I rollback to the start.

Then, looking my javascript code and to be more concrete, this part:

if ( $this.find("input[type='file']").val() ) {
    formdata.append("characteristic[element_"+i+"][file]", fileDOM.files[0], fileDOM.files[0].name);
}

That gave me on the server the ugly array, so I thought that the array was the problem and i decided to remove the characteristic[] array and use $_POST and $_FILES as the array container for my data. Also, I removed the '["file"]' index when appending the files to the formdata.

$(".characteristicData").each(function(i, v) {

    $this = $(this);
    fileDOM = $this.find("input[type='file']")[0];

    formdata.append("element_"+i+"[id_characteristic]", $this.attr("id"));
    formdata.append("element_"+i+"[items]", $this.find("textarea").val());

    if ( $this.find("input[type='file']").val() ) {
        formdata.append("element_"+i, fileDOM.files[0], fileDOM.files[0].name);
    }

});

Now, when I send the data to the server and it prints the values I get the expected values for my files.

Array
(
    [element_0] => Array
        (
            [name] => 001.png
            [type] => image/png
            [tmp_name] => E:\wamp\tmp\php9BA.tmp
            [error] => 0
            [size] => 578
        )

)

Upvotes: 1

Related Questions