0

I have a form with deep multidimensional inputs like so:

<form id="theForm">
 <input type='text' name='one[two][three][]' />
 <input type='text' name='one[two][three][]' />
 <input type='text' name='four[five][six][seven]' />
 <input type='text' name='eight[nine][ten]' />
</form>

I am trying to send the values via AJAX in the same format as if the form was submitted normally. What I mean is, if I were to hit the submit button, in PHP, $_POST would look like this. This is what I want:

array( 'one' => array( 'two' => array('three'=>array( [0] => "", [1] => "" ) ) ),
       'four' => array( 'five' => array ('six' => array( 'seven' => "" ) ) ),
       'eight' => array( 'nine' => array( 'ten' => "" ) ) )
     )

I am essentially trying to AJAX the form submission. When I do

$("#theForm").serializeArray()

And the send that over $.post() my $_POST looks like this:

array( [0] => array( "name" => string "one[two][three][]",  value=>"")
       [1] => array( "name" => string "one[two][three][]",  value=>"")
       [2] => array( "name" => string "four[five][six][seven]",  value=>"")
       [3] => array( "name" => string "eight[nine][ten]",  value=>"")
     )

This is of no use to me. I need to preserve the multidimensional structure I outlined before. I suppose I could walk through the array and chop up the string to recreate what I need, but this seems asinine to me. Is the a jQuery friendly way to accomplish this?

I've read the other posts about how jQuery can send multidimensional arrays just fine, so maybe the question I need to ask is, how do I extract my form data, keeping it in a multidimensional array?

parker.sikand
  • 1,371
  • 2
  • 15
  • 32
  • 1
    [Check out this answer](http://stackoverflow.com/a/1186309/575527). This turns a form into a JS object which may preserve the key-value structure of the form array by properly turning elements to objects and arrays. – Joseph Feb 27 '13 at 19:05
  • Can you show the code where you send the data via AJAX? – gen_Eric Feb 28 '13 at 15:38

2 Answers2

4

My guess is when you are making the AJAX call you are doing:

data: {data: $("#theForm").serializeArray()}

Don't do that, just set data to the value of serializeArray.

data: $("#theForm").serializeArray()

EDIT: You said you are using $.post, and I assume you are doing this:

$.post('/your/url', {data: $("#theForm").serializeArray()}, function(){});

In order for it to work, you need to do it this way:

$.post('/your/url', $("#theForm").serializeArray(), function(){});
gen_Eric
  • 223,194
  • 41
  • 299
  • 337
  • That's not what I'm doing nor is that the problem. The problem is that serializeArray does not structure the data according to the various array levels. It is "flat", with the "name" attribute set to "whatever[the][name][was]". Seems like the only way to do what I want is to just do it yourself. – parker.sikand Feb 28 '13 at 15:27
  • 2
    @parker.sikand: This is *exactly* what you are doing, though I suspect you are using `$.post` instead of `$.ajax`. `serializeArray` returns an array of objects with `name` and `value` keys. When passed to `$.param` (which is done automatically by jQuery), it's converted to a query string in the format you expect. If you send the data like `{data: $("#theForm").serializeArray()}`, then it won't be sent correctly. – gen_Eric Feb 28 '13 at 15:32
  • @parker.sikand: It's ok, don't beat yourself up :) – gen_Eric Mar 01 '13 at 18:30
  • For future googlers: I had the same thought proccess as @parker.sikand and yes, the answer is really correct. :) Thank you! – Petr Cibulka Jan 30 '17 at 13:05
2

Accepted answer is totally correct. As a side note, if you need to add other data to the array of post data, you just need to push it onto the array in the format {name: "", value: ""}

In my case, I wanted to add a value based on a button that the user clicked, in addition to the values from all of the inputs in the form. So all you have to do is:

var data = $("#myForm").serializeArray();
data.push({name: "btnVal", value="button_a"});

And make sure you post like:

$.post("/some/url", data, function(){});
parker.sikand
  • 1,371
  • 2
  • 15
  • 32