IE DOM Bugs
Posted by Tom on February 7th, 2006I’ve been working on a Javascript project where it’s necessary to create input elements (radio buttons and checkboxes) dynamically. With a functional DOM, it takes only a couple of lines of code, and works fine in Firefox and Safari. Too bad IE isn’t as DOM compatible as it claims to be.
After several searches, I discovered IE doesn’t allow the name attribute to be changed after the element is created—and it can’t be set in a DOM compatible way during creation.
Bennett McElwee suggested a solution in his blog that is nicely cross-browser; anything other than IE throws an exception and gets created properly. (I suspect modifying the parent node’s innerHTML would work as well.)
function createElement(type, name) {
var element = null;
try {
// First try the IE way; if this fails then use the standard way
element = document.createElement('<'+type+' name="'+name+'">');
} catch (e) {
// Probably failed because we’re not running on IE
}
if (!element) {
element = document.createElement(type);
element.name = name;
}
return element;
}
And your type attribute too
Another part of the project requires we transform checkboxes to radio buttons and hidden fields. This could be accomplished through a page reload, but it’s overkill for such a small change. Once again, in truly DOM-compliant browsers, this requires only a couple of lines of code:
element.setAttribute("type", "radio");
The MSDN reference for the type attribute says:
As of Microsoft Internet Explorer 5, the
typeproperty is read/write-once, but only when aninputelement is created with thecreateElementmethod and before it is added to the document.
QuirksMode has a bug report for this, complete with test page and workaround submitted by Stijn Peeters. Stijn admits the workaround needs a little bit of cleanup.
Essentially, his solution is to always remove the element, and recreate a modified one. (See the bug above!) Here’s my solution:
try {
element.setAttribute("type", "radio");
} catch (e) {
var newElement = null;
var tempStr = element.getAttribute("name");
try {
newElement = document.createElement("<input type=\"" +typeStr+ "\" name=\"" +tempStr+ "\">");
} catch (e) {}
if (!newElement) {
newElement = document.createElement("input");
newElement.setAttribute("type", "radio");
newElement.setAttribute("name", tempStr);
}
if (tempStr = element.getAttribute("value")) {
newElement.setAttribute("value", tempStr);
}
element.parentNode.replaceChild(newElement, element);
}
Update:
Aaron over at easy-reader.net encountered the same problem a few months before I did. His solution is similar, and the comments there are good. If only I had found it sooner!

Been trying something similar… it all works but I can’t seem to get the focus back on the input field. Any workarounds?
function CC_changetype(target, wrde) {
if(document.getElementById(target.id).value == wrde)
{
replace = document.getElementById(target.name);
var val = replace.value;
var id = replace.id
var parent = replace.parentNode;
var sibling = replace.nextSibling;
var newel = document.createElement(’input’);
newel.setAttribute(’type’, ‘password’);
newel.setAttribute(’value’, ”);
newel.setAttribute(’id’, id);
newel.setAttribute(’maxLength’, ‘8′);
parent.removeChild(replace);
parent.insertBefore(newel, sibling);
//settimeout(’document.getElementById(newel.getAttribute(”id”)).focus();’,1000);
}
}
Left by Bartez on March 27th, 2006