Convert form data to a JS object with jQuery, including group values

advertisements

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.


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/