0

I have multiple input tags in a form, and I need to prepare all values to be send through an Ajax request. Here is an example of input fields :

<form>
  <input name="foo" value="1">
  <input name="foo1" value="1">
  <input name="bar[]" value="2">
  <input name="bar[]" value="2">
  <input name="fooBar[a][]" value="3">
  <input name="foobar[b][]" value="3">
</form>

Expected result :

{
  foo : "1",
  foo1 : "1",
  bar : ["2", "2"],
  fooBar : { a : ["3"], b : ["3"]}
}

or :

  {
    foo : "1",
    foo1 : "1",
    "bar[0]" : "2",
    "bar[1]" : "2",
    "fooBar[a][0]" : "3",
    "fooBar[b][0]" : "3"
  }  

I have no idea on how and where to start building my function, so maybe anyone has an idea and can give me a hint on how this may be done in plain javascript.

John
  • 7,500
  • 16
  • 62
  • 95
  • Are you willing to use jQuery? It has a simple function `serialize()` that does all the work for you. – Barmar Apr 16 '13 at 18:29
  • This looks like the output from Prototype's `serialize()` function. Is it? – FrankieTheKneeMan Apr 16 '13 at 18:30
  • 1
    @Barmar no, I would like to use plain javascript – John Apr 16 '13 at 18:34
  • 2
    It's pretty complicated. Use `getElementsByTagName()` to list all the input elements within the for. Write a `for` loop that iterates over them. It gets the name and value and puts them into the object you're creating. You'll need to check for names that end in `[]` and create an array that you accumulate. When you've done this and it doesn't work, post your code and someone should be able to help you fix it. – Barmar Apr 16 '13 at 18:40
  • 1
    you don't need `getElementsByTagName()` you can use `document.forms.formName.elements` to get the elements in the form. – rlemon Apr 16 '13 at 18:50

2 Answers2

1

Thanks for ideas. I just figured out what exactly I want to do with this, and I solved this problem in a easy way. Basically I need to send values throught Ajax request so I simply need a QueryString, so here is my simple solution which seems to work exactly as I need :

var elements = form.elements;

var data;

for(var i = -1, j = elements.length; ++i < j;)
{
  if(elements[i].name)
  {
    data += "&" + elements[i].name + "=" + encodeURIComponent(elements[i].value);
  }
}
John
  • 7,500
  • 16
  • 62
  • 95
0

It's not perfect and it is kind of a mix between your two expected outputs but it's simple and hopefully you can understand what is happening.

function serializeForm(frm) {
    var ret = {};
    [].forEach.call(frm.elements, function (element) {
        if (ret.hasOwnProperty(element.name)) {
            if (!Array.isArray(ret[element.name])) {
                ret[element.name] = [ret[element.name]];
            }
            ret[element.name].push(element.value);
        } else {
            ret[element.name] = element.value;
        }
    });
    return ret;
}

console.log(serializeForm(document.forms.frm));

outputs

bar[]: ["2","2"]
foo: "1"
foo1: "1"
fooBar[a][]: "3"
foobar[b][]: "3"

http://jsfiddle.net/rlemon/FFMb7/ you can see a demo here.

To split apart the foobar stuff (assuming the caps was a typo) you will need to do a bit more work and probably use regular expressions to pull apart the first part of the array and the values in the brackets. I'm not even going to attempt that for you because I hate regular expressions :P so hopefully this output will work.

Update: if you are actually trying to serialize the form for http submission then you should use a more standard form. form serialize javascript (no framework) as described here.

Community
  • 1
  • 1
rlemon
  • 17,518
  • 14
  • 92
  • 123