0

Edited:

$.fn.serializeObject = function() {
var o = {};
var a = this.serializeArray();
$.each(a, function() {
    var value = this.value || '';
    if (/^\d+$/.test(value))
        value = +value;

    if (o[this.name] !== undefined) {
        if (!o[this.name].push) {
            o[this.name] = [o[this.name]];
        }
        o[this.name].push(value);
    } else {
        o[this.name] = value;
    }
});
return o;
};`

Edited to hopefully make clearer.

Having difficulty wrapping my head around this - sleep deprivation = madness.

I have a form that simply serialises the data into JSON and stores it for later use.

<form id="form" method="post">

a? <input class="number" type="text" name="a" size="5" maxlength="5"/><br/>

Item 1:

Type?:<br/>
<select size="2" name="type">
    <option value="1">b</option>
    <option value="2">c</option>
</select>

d:<input class="number" type="text" name="d" maxlength="2" size="2"/> <br/>
e:<input class="number" type="text" name="e" maxlength="2" size="2"/> <br/>

<p>Item 2:</p>


Type?:<br/>
<select size="2" name="type">
    <option value="1">b</option>
    <option value="2">c</option>
</select>

d:<input class="number" type="text" name="d" maxlength="2" size="2"/> <br/>
e:<input class="number" type="text" name="e" maxlength="2" size="2"/> <br/>

<input type="submit" />

when the form is serialised the result I get is:

JSON{
    "a":1,
    "type":[1,2],
    "d":[99,33],
    "e":[99,33]
}

what I need is the typical tree structure of JSON something where each item has its own level, something like:

{
"a": "1",

"item1": 
{
    "type": "1",
    "d": "99",
    "e": "99",
},
"item2": 
{
 "type": "2",
 "d": "33",
 "e": "33",
 }

Ideally I'd like to have an option whereby the user can state how many items the form should request information for but I need a basic working example first.

once I have this data I'm then converting it into JSON and would like a tree like structure if possible. Any help appreciated. This post How to serialize a form into an object (with tree structure)? helps a lot but its the structure of the HTML I'm having issues with. Thanks again.

Community
  • 1
  • 1
null
  • 3,469
  • 7
  • 41
  • 90
  • 1
    I'm having a hard time understanding your problem ? Consider rewording. Are you trying to dynamically template the Selects and fb input ? – Nix Jan 05 '14 at 20:16
  • @Nix - sorry for the confusion. I need details of several items. Each item is the same object type and has the same fields but will have different values. Does that help at all? – null Jan 05 '14 at 20:31
  • Not really... maybe someone else can explain what you need. Maybe start with what you can't figure out ? – Nix Jan 05 '14 at 20:34
  • @Nix - I've updated the question with what I have and the output. Sorry again. – null Jan 05 '14 at 20:36
  • @Nix - updated just now, apologies if still not clear – null Jan 05 '14 at 20:44
  • much better! Only other question I have is where is the code that is serializing the form ? – Nix Jan 05 '14 at 20:51
  • @Nix - Thanks :) - I've added the serialise code, it's the same as from css-triks – null Jan 05 '14 at 21:02

2 Answers2

0

I'd introduce new html attribute:

<input data-item="1" class="number" type="text" name="d" maxlength="2" size="2"/>
<select data-item="1" size="2" name="type"> ...

and then I'd use

$(this).attr('data-item');

to read value and place it in right object. Other option is to get elements only for specified item (in some loop):

$('input[data-item="1"], select[data-item="1"]').each(...);

EDIT I see no pretty way of using serializeArray() to achieve this, but I'd go for item number in name attribute (name="type1") or again for loop with i as item number:

$('[data-item="'+i+'"]', this).serializeArray();
zola
  • 66
  • 4
0

A quick and dirty way would be this: change the name of your inputs based on their item number:

<input name="item1.a" ... />
<input name="item2.a" ... />
<input name="item3.a" ... />

Then modify the serializeObject() to look for the dots:

...
    $.each(a, function() {
        var value = this.value || '';
        if (/^\d+$/.test(value))
            value = +value;

        if ( this.name && this.name.indexOf('.') )
        {
            var split = this.name.split('.');
            o[ split[0] ] = o[ split[0] ] || {};
            o[ split[0] ][ split[1] ] = value
        }
        else if (o[this.name] !== undefined) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(value);
        } else {
            o[this.name] = value;
        }
    });
...

NOTE: This code isn't perfect, but it will get you in the right direction!

redolent
  • 4,159
  • 5
  • 37
  • 47
  • Hi, thanks for taking the time to suggest a solution. I don't mind quick but I do like pretty :) Could this be modified to be dynamic at all? The end game would be to ask the user how many items were to be added and then generate the fields that would need to be populated – null Jan 05 '14 at 21:29
  • Yeah, just combine my solution with @zola's and use `$(this).attr('data-item')` in place of `this.name` in the first 'if' statement. – redolent Jan 05 '14 at 21:38