rwkiii rwkiii - 3 months ago 8
Ajax Question

Change structure of associative array posted by Ajax

My Ajax is posting form fields created using an associative array and everything works, but the structure of the returned data isn't correct.

The form fields:

<input id="my_array[][system]" type="text" value="" name="my_array[0][system]">
<textarea id="my_array[][note]" type="text" value="" name="my_array[0][note]"></textarea>

<input id="my_array[][system]" type="text" value="" name="my_array[1][system]">
<textarea id="my_array[][note]" type="text" value="" name="my_array[1][note]"></textarea>

<input id="my_array[][system]" type="text" value="" name="my_array[2][system]">
<textarea id="my_array[][note]" type="text" value="" name="my_array[2][note]"></textarea>


The Ajax call:

$.ajax(ajaxurl, {
type: "POST",
dataType: "json",
data: {
action: "update_postmeta",
post_id: post_id,
nonce: nonce,
my_array: (function () {
var my_array = {};
$('input:text[name^="my_array"], textarea[name^="my_array"]')
.each(function () {
my_array[this.name] = $(this).val();
});
return my_array;
})()
},
success: function (response) {
alert(response);
},
error: function (jqXHR, textStatus, errorThrown) {
alert("Error: " + textStatus + '\r\n\r\n' + errorThrown);
}
})


Results in:

array(3) (
[my_array[0] => array(2) (
[system] => (string) Some system 1
[note] => (string) Note 1
)
[my_array[1] => array(2) (
[system] => (string) Some system 2
[note] => (string) Note 2
)
[my_array[2] => array(2) (
[system] => (string) Some system 3
[note] => (string) Note 3
)
)


I need it to be:

array(3) (
[0] => array(2) (
[system] => (string) Some system 1
[note] => (string) Note 1
)
[1] => array(2) (
[system] => (string) Some system 2
[note] => (string) Note 2
)
[2] => array(2) (
[system] => (string) Some system 3
[note] => (string) Note 3
)
)


The solution is within the following code:

my_array: (function () {
var my_array = {};
$('input:text[name^="my_array"], textarea[name^="my_array"]')
.each(function () {
my_array[this.name] = $(this).val();
});
return my_array;
})()


But my attempts just break it worse. How do I get the desired structure? Basically, I need the second dimension to be index keys instead of 'my_array[1' etc.

Answer

To ensure you get the right numeric keys for the right values on the php side, I think you are going to have to extract the names of the inputs via regular expressions and assign manually.

For example, inside the each loop:

var parsedName = this.name.match(/^my_array\[(\d+)\]\[(.*)\]$/);
my_array[parsedName[1]] = my_array[parsedName[1]] || {};
my_array[parsedName[1]][parsedName[2]] = $(this).val();