I wrote some JavaScript to allow editing a list of items within an HTML form, including adding and removing items. Got it working in Firefox. When trying it in Internet Explorer, I found that any added items were not being submitted with the form.
Long story short... lots of simplification, debugging, figured out what line is triggering IE to ignore the new form input. So the behavior problem is solved.
But now I must ask: Why? Is this an IE bug?
Here is the simplified code:
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function add() {
div = document.getElementById("mylist");
// *** Adding text here works perfectly fine. ***
div.innerHTML += " ";
e = document.createElement("input");
e.setAttribute("type", "text");
e.setAttribute("name", "field3");
e.setAttribute("value", "--NEWVALUE--");
div.appendChild(e);
// *** Adding text here works perfectly fine in Firefox, but for
// Internet Explorer it causes field3 to not be submitted. ***
//div.innerHTML += " ";
}
</script>
</head>
<body>
<form action="" method="get">
<div id="mylist">
<input type="text" name="field1" value="value1" />
<input type="text" name="field2" value="value2" />
</div>
<a href="javascript:" onclick="add()" />Add</a>
<input type="submit" value="Submit" />
</form>
</body>
</html>
To try it out, do the obvious: load in IE, click Add, click Submit, look what's in the address bar. If you uncomment the last line in add()
, IE will suddenly stop reporting field3
. It works fine either way in Firefox.
Any ideas? A curious mind wants to know. (And how would I add text there if needed, in a portable fashion, so IE is happy?)
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.