0

I have a form with inputs using this naming convetion:

  <input class="xxlarge" name="note[url]" id="url" placeholder="URL">

So, I'm using this script (found on StackOverflow) that serializes form data into JSON.

$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
    if (o[this.name] !== undefined) {
        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;
};

and on the output I have this:

  {"note[url]":"URL","note[title]":"TITLE"}

I'd like to know how to transform this script to get output like this:

  {"url":"URL","title":"TITLE"}

I'm handling this from with rather standard, documented code block (using function, described above):

      $(function() {
      $('form').submit(function() {
        $('#result').html(JSON.stringify($('form').serializeObject()));
          $.post(
              "/api/create",
              JSON.stringify($('form').serializeObject()),
              function(responseText){
                  $("#result").html(responseText);
              },
              "html"
          );
          return false;
      });

Thanks in advance!

Community
  • 1
  • 1
Ghinzu
  • 39
  • 7
  • I think a little more of your code would be helpful here. – Alan Moore Sep 27 '11 at 21:55
  • Given that field name notation, are you using a PHP server? Any reason you need to split those values up in JS? PHP will happily convert them to an array for you once the data's submitted. – Marc B Sep 27 '11 at 22:02

2 Answers2

1

Not sure where your 'note' part is coming from. May be something you could fix via the name attributes in your markup. Otherwise you could always do something like:

function renameKeys(obj) {
    var 
        result = {},
        key,
        check,
        noteReg = /^note\[([^\]]+)\]$/;

    for(key in obj) {
        result[(check = key.match(noteReg)) === null ? key : check[1]] = typeof obj[key] == 'object' && toString.call(obj[key]) == '[object Object]' ? renameKeys(obj[key]) : obj[key];
    }

    return result;
}

which can be used to make a new object with the keys you want.

renameKeys({"note[url]":"URL","note[title]":"TITLE"}); 
// { url: 'URL', title: 'TITLE' }

renameKeys({"note[url]":"URL","note[title]":"TITLE", anotherObj: { thingA: 1234, 'note[thingB]': 9492}});
// { url: 'URL', title: 'TITLE', anotherObj: { thingA: 1234, thingB: 9492 } }

Beware, though, that if you have something like a key of note[asdf] and a key of asdf then whichever is iterated over last will overwrite the other.

Marshall
  • 4,716
  • 1
  • 19
  • 14
1

I would suggest parsing the string into a JS object, changing the keys in a for loop, then stringifying it when you're done. Like so:

// turn the string into a JS object
var data = JSON.parse('{"note[url]":"URL","note[title]":"TITLE"}');
var newData = {};
// step through each member
for(key in data) {
  // Regular expressions to find the brackets
  var newKeyStart = key.search(/note\[/) + 5;
  var newKeyEnd = key.search(/\]/);
  // pull out the desired part of the key
  var newKey = key.substr(newKeyStart,  newKeyEnd - newKeyStart);
  // insert into new data object
  newData[newKey] = data[key];
  }
// turn back into JSON again
var newJSON = JSON.stringify(newData);
visum
  • 357
  • 3
  • 10
  • Not that you can't depend on the JSON library to be present on older browsers. If you're concerned about that, include Douglas Crockford's JSON library: https://github.com/douglascrockford/JSON-js/blob/master/json2.js – visum Sep 27 '11 at 22:23