Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

special case of serializing form to a javascript object

building upon the $.fn.serializeObject() function from this question, i'd like to be able to support "dot notation" in my form names, like so:

<form>
    <input name="Property.Items[0].Text" value="item 1" />
    <input name="Property.Items[0].Value" value="1" />
    <input name="Property.Items[1].Text" value="item 2" />
    <input name="Property.Items[1].Value" value="2" />
</form>

given that $('form').serializeArray() produces the following:

[{"name":"Property.Items[0].Text","value":"item 1"},
 {"name":"Property.Items[0].Value","value":"1"},
 {"name":"Property.Items[1].Text","value":"item 2"},
 {"name":"Property.Items[1].Value","value":"2"}]

how could i achieve the desired result below:

{Property: {Items: [{Text: 'item 1', Value: '1'},
                    {Text: 'item 2', Value: '2'}]} }

any help would be appreciated.

EDIT: to be specific, the desired code would be added to the serializeObject extension so that in addition to the way it works now, it would also support the above convention. here's the existing method for convenience.

$.fn.serializeObject = function() {
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};

EDIT 2: feeding off the answer provided, here's my current implementation:

$.fn.serializeObject = function() {
  var o = {};
  var a = this.serializeArray();
  var regArray = /^([^\[\]]+)\[(\d+)\]$/;

  $.each(a, function(i) {
      var name = this.name;
      var value = this.value;

      // let's also allow for "dot notation" in the input names
      var props = name.split('.');
      var position = o;
      while (props.length) {
          var key = props.shift();
          var matches;
          if (matches = regArray.exec(key)) {
              var p = matches[1];
              var n = matches[2];
              if (!position[p]) position[p] = [];
              if (!position[p][n]) position[p][n] = {};
              position = position[p][n];
          } else {
              if (!props.length) {
                  if (!position[key]) position[key] = value || '';
                  else if (position[key]) {
                      if (!position[key].push) position[key] = [position[key]];
                      position[key].push(value || '');
                  }
              } else {
                  if (!position[key]) position[key] = {};
                  position = position[key];
              }
          }
      }
  });
  return o;
};

you can see it in action here

like image 608
Omer Bokhari Avatar asked Oct 14 '22 20:10

Omer Bokhari


1 Answers

This solution is a bit static. But it should do the trick:

var serialized = $.fn.serializeObject(),
            properties = {},
            property = [],
            position = {},
            key = '',
            n = 0,
            matchName = '',
            i = 0;

        for (i = 0; i < serialized.length; i += 1) {
            property = serialized[i].name.split('.');
            position = properties;
            while (property.length) {
                key = property.shift();
                if (key.match(/\[\d+\]/) && key.match(/\[\d+\]/).join().match(/\d+/g) ) {
                    matchName = key.match(/\w+/)[0]
                    n = parseInt(key.match(/\[\d+\]/).join().match(/\d+/g), 10);
                    if (!position[matchName]) {
                        position[matchName] = [];
                    }

                    if (!position[matchName][n]) {
                        position[matchName][n] = {}
                    }

                    position = position[matchName][n]
                } else {
                    if (!property.length) {
                        position[key] = serialized[i].value
                    } else {
                        if (!position[key]) {
                            position[key] = {};
                        }
                        position = position[key]
                    }
                }

            }
        }

        console.log(properties);
like image 128
fredrik Avatar answered Nov 04 '22 00:11

fredrik