marioizquierdo / jquery.serializeJSON

Serialize an HTML Form to a JavaScript Object, supporting nested attributes and arrays.
MIT License
1.71k stars 433 forks source link

Nested array within an Array Object #88

Closed randallmlough closed 5 years ago

randallmlough commented 6 years ago

I was hoping to figure out how I can have an array or an array object within another array object.

my desired output

{
  "staff": [{
    "name": "john doe",
    "another_array": [
        "something",
        "something2"
    ],
    "array_obj": [{
         "title": "something",
         "desc": "foobar"
    }]
  }]
}

I've tried something like

<input name="staff[]another_array[]">

and something like...

<input name="staff[]array_obj[][title]">

But none of the above works. It doesnt appear you can have nested arrays. Is this true?

Windman1320 commented 6 years ago

There are something wrong in your code : <input name="staff[]another_array[]"> ,to achieve your ideal result, it should be like this:<input name="staff[another_array][]"> . You'd better take a look at the README.md .The full code is here :

<!-- nested attributes -->
<input type="text" name="staff[name]"         value="john doe" />
<input type="text" name="staff[another_array][]"  value="something" />
<input type="text" name="staff[another_array][]"  value="something2" />

<!-- array -->
<input type="text" name="staff[array_obj][title]"             value="something" />
<input type="text" name="staff[array_obj][desc]"             value="foobar" />
randallmlough commented 6 years ago

Thanks for the quick reply @cappuccinoqi! Your suggestion wasn't the exact output I was looking for, but tinkering with it some more based on your guidance I got it work using the following structure

<input type="text" name="staff[][simpleArray][]" value="person 1 - simple array 1">
<input type="text" name="staff[][arrayObj][][title]" value="person 1 - Array obj title 1">

That results in

"staff": [{
        "simpleArray": ["person 1 - simple array 1", "person 1 - simple array 2"],
        "arrayObj": [{
            "title": "person 1 - Array obj title 1",
            "desc": "person 1 - Array obj description 1"
        }]
    }]
Windman1320 commented 6 years ago

aha , I did this in a hurry, perhaps it was because Chrome Debug Mode doesn't show the result well.Good to hear that my suggestion is useful.

Windman1320 commented 6 years ago

@randallmlough If you don't mind ,would you like to tell me how can you get that result ? My output in Chrome is not tidy as your result.

marioizquierdo commented 6 years ago

Using the array[][nestedObjKey][] syntax works, but it will add keys to the object only if the key does not exist, and create new object elements if the key does not exist... Kind of magic behavior that may work great or be super-confusing.

To avoid confusion, I recommend explicitly specifying the array indexes (use [0], [1], [2], ... instead of just []):

<input type="text" name="staff[0][name]" value="john doe" />
<input type="text" name="staff[0][another_array][0]" value="something" />
<input type="text" name="staff[0][another_array][1]" value="something2" />
<input type="text" name="staff[0][array_obj][0][title]" value="something" />
<input type="text" name="staff[0][array_obj][0][desc]" value="foobar" />

And then use serializeJSON with the option useIntKeysAsArrayIndex:

$('input').serializeJSON({useIntKeysAsArrayIndex: true});

This way you get exactly what you would expect:

{
  "staff": [{
    "name": "john doe",
    "another_array": [
        "something",
        "something2"
    ],
    "array_obj": [{
         "title": "something",
         "desc": "foobar"
    }]
  }]
}