2

I want to serialize my form data into a JSON object like it's described in the following thread: Convert form data to JavaScript object with jQuery However besides of single fields which go as they appear in the form I have fields which I want to group into separate objects. For example, I have 2 fields - startDate and endDate. And in JSON object I want to achieve the following structure:

"dates" : {
     "startDate" : "03/19/2014",
     "endDate" : "03/27/2014"
},

So, I want to get the values for firstDate and endDate, combine them in an object dates and add to the object which contains the values for separate fields.

Can anybody give me a hint on how can this be achieved? Is there a way to define a some kind of JSON "template" and replace the values of properties with the values from the form?

And a more deep example which I'll need to support:

"demographic" : {
  "declaredGender" : "any",
      "estimatedGender" : "female",
      "estimatedGenderConfidence" : 50,
      "declaredYearOfBirth" : {
          "from" : "1960",
          "to" : "1990"
      },
      "estimatedYearOfBirth" : {
          "from" : "1980",
          "to" : "1990"
      },
      "estimatedYearOfBirthConfidence" : 50
},

Thanks.

Community
  • 1
  • 1
cycero
  • 4,547
  • 20
  • 53
  • 78

2 Answers2

1

What about something like this:

$.fn.serializeObject = function(options) {

    var data = $(this).serializeArray(),
        obj = {};

    $.each(data, function(i, el) {
        var key = el.name;
        if (el.name in options) {
            obj[options[key]] = obj[options[key]] || {};
            obj[options[key]][key] = el.value;
        }
        else {
            obj[key] = el.value;
        }
    });

    return obj;
};

You can use it this way:

var data = $('form').serializeObject({startDate: 'dates', endDate: 'dates'});

So you say in configuration that you want startDate field to go into dates group and so on. You also can define multiple groups, for example:

$('form').serializeObject({
    startDate: 'dates',
    endDate: 'dates',
    firstName: 'user',
    lastName: 'user'
});

Demo: http://jsfiddle.net/dfsq/UwFTr/1/


UPD

For nested groups plugin can look like this:

$.fn.serializeObject = function(options) {

    function namespace(obj, keys, name, value) {
        keys = keys.split('.');
        var o = obj;
        for (var i = 0; i < keys.length; i++) {
            o[keys[i]] = o[keys[i]] || {};
            o = o[keys[i]];
        }
        o[name] = value;
        return obj;
    }

    var elements = $.makeArray($.prop(this[0], "elements")),
        obj = {};

    $.each(elements, function(i, el) {
        if (!el.name || $(el).is(":disabled")) return;

        var group = $(el).attr('group');

        if (!group) {
            obj[el.name] = $(el).val();
        }
        else {
            obj = namespace(obj, group, el.name, $(el).val());
        }
    });

    return obj;
};

Use it in HTML:

<input type="date" name="startDate" group="event.dates" value="2014-03-26">

Demo: http://jsfiddle.net/dfsq/UwFTr/2/

dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Thanks, this works great for 2 levels, but there are cases with deeper structures. I've updated my question with such an example. This function won't work for that. – cycero Mar 26 '14 at 12:38
  • Any solution for such a scenario? – cycero Mar 26 '14 at 13:14
-1

You could group the inputs using divs or other elements and use an attribute such as id or a data- prefixed html5 attribute for the json key. In the below example I have used $.attr() to pluck id's for the groups, and name for the individual inputs.

http://jsfiddle.net/A9XvJ/

joefitter
  • 1
  • 1