Death to bad DOM Implementations

I just encountered a DOM implementation issue in IE which took about three hours to solve (and like a year off my life). The story goes like this:

I could not, for the life of me, figure out why a form submitted in Firefox was coming through perfectly while it was missing fields in IE. The form in question has some normal fields and some dynamically generated ones (if JavaScript is enabled). The normal stuff was coming through fine, but I was getting no values for the dynamically generated fields when the form was submitted in IE. I checked the $_REQUEST variable (I am using PHP) to see what was coming through, just to be sure.

I immediately figured it was missing name attributes, but I was using the proper syntax to create the input elements via the DOM (note: the actual JS is more generic than this)

var inpt = document.createElement('input');
inpt.setAttribute('name', 'company');
view raw not-in-IE.js hosted with ❤ by GitHub

Indeed, when I looked at the page through the Web Accessibility Toolbar’s View Generated Source, it was indeed missing the name attribute:

<INPUT id=company maxLength=255>

After about another hour or two of fruitless Google-ing, I finally typed in the magic phrase (setting the name attribute in Internet Explorer) and ended up on Bennett McElwee’s blog post of the same name. Suddenly it was all clear and (as I expected) IE’s botched implementation of the DOM’s createElement function was to blame.

According to the MSDN page on the name attribute (linked and quoted in the blog entry):

The NAME attribute cannot be set at run time on elements dynamically created with the createElement method. To create an element with a name attribute, include the attribute and value when using the createElement method.

It continued with the following example:

var oAnchor = document.createElement("<A NAME='AnchorName'></A>");

The script “solution” Bennett posted was somewhat of a red herring, however, as Firefox would actually execute the createElement intended for IE and end up with an element named “<input name=”company” />” which would be rendered on the page as

<<input name="company" /> id="company" maxlength="255" />

Perhaps you can see why this would be problematic.

I augmented Bennett’s script slightly and renamed the function createElementWithName so I wouldn’t have to use it on every element I created in the script:

function createElementWithName(type, name) {
var element;
// First try the IE way; if this fails then use the standard way
if (document.all) {
element =
document.createElement('< '+type+' name="'+name+'" />');
} else {
element = document.createElement(type);
element.setAttribute('name', name);
}
return element;
}

I am not a super fan of the reference to document.all as it feels so much like browser sniffing. I am up for suggestions to improve the function if you have any ideas.

Anyway, I am posting this to hopefully save someone else from the major headache I had today.

Like it? Share it

Share on LinkedIn

Share on Google Plus

View comments on this entry