IE is not submitting dynamically added form elements

Is this an IE bug?

Seems so. When you create an <input> element through DOM methods, IE doesn't quite pick up the ‘name’ attribute. It's sort-of-there in that the element does submit, but if you try to get an ‘innerHTML’ representation of the element it mysteriously vanishes. This doesn't happen if you create the element by writing directly to innerHTML.

Also if you use DOM Level 0 form navigation methods, like ‘myform.elements.x.value’, access through the ‘elements’ array may not work (similarly the direct ‘myform.x’ access some people misguidedly use). In any case these days you might prefer getElementById().

So either use innerHTML or use DOM methods; best not to mix them when creating form fields.

This is documented (see ‘Remarks’) and finally fixed in IE8.

In any case, never do:

div.innerHTML+= '...';

This is only syntactical sugar for:

div.innerHTML= div.innerHTML+'...';

In other words it has to serialise the entire child HTML content of the element, then do the string concatenation, then re-parse the new string back into the element, throwing away all the original content. That means you lose anything that can't be serialised: as well as IE's bogus half-created ‘name’ attributes that also means any JavaScript event handlers, DOM Listeners or other custom properties you have attached to each child element. Also, the unnecessary serialise/parse cycle is slow.


IE is very picky about changing some built-in properties at runtime. For example, the name of an input element cannot be changed while set.

Two things I would try if I were you:

  1. Instead of using setAttribute(), try setting the name, type and value properties explicitly:

    e.name = "text";

  2. If this doesn't work, you may have to include all these attributes into the document.createElement() call:

    var e = document.createElement("<input type='text' name='field'>");

    this may actually throw an exception in some browsers. So the best cross browser way to go would be:

.

var e;
  try {
    e = document.createElement("<input type='text' name='field'>");
  } catch (ex) {
    e = document.createElement("input");
    e.type = 'text';
    e.name = 'field';
  }
  e.value = 'value';

Thank you bobince and levik for your answers. Using those, and some more experimentation, here are my conclusions:

  1. Yes it is an IE bug.

  2. IE 8 fixes the bug according to Microsoft: "Internet Explorer 8 and later can set the NAME attribute at run time on elements dynamically created with the createElement method."

  3. The bug is this: Calling e.setAttribute("name", "field3") only kind-of sets the name. It will work if nothing else happens to the element, but if requested to serialize, the name is not serialized. So when I said innerHTML += " " that forced a serialization, which lost the name, so it was not recovered upon deserialization. No name, no inclusion in form submission.

  4. Workaround #1: e = document.createElement("<input name='field3' />") would work, even when faced with serialization.

  5. Workaround #2: Rather than adding text using innerHTML +=, I can append a text element like this: div.appendChild(document.createTextNode(" "));. I had figured there must be a better way of adding text, and now I know it :-).

Cheers,
--jsf