IE6 radio buttons with DOM

2006-04-30 01:09:00

Update: Something has recently happened in the Scooby codebase that broke this fix. The only related change I can think of is that the actual form tags moved from a JavaScript-generated innerHTML call, to being embedded directly in the initial JSP page for the Scooby UI.

So rather than playing more pattycake with this silly issue, I just pulled out a can of innerHTML whoop-ass, and created a little branch in the code for IE just for radio buttons and checkboxes. It's ugly, but it will work reliably.

Note that the following fix is not recommended, but I'll leave the original post here for posterity's sake ...

In the process of working on some DOM code for Scooby that produces form elements, I ran into some really interesting speed bumps making sure the code works properly in IE6. One of them dealt with dynamically created radio buttons.

IE ("As of Internet Explorer 5 ...") purportedly is able to use the standard createElement method for all types of input elements. However, with my code IE would create the buttons, but they would not work. Quite the buzzkill. Posts like this one and this one confirmed that something is generally awry with the IE's DOM methods for radio buttons.

Then I then noticed a little extra disclaimer in the IE docco:

Attributes can be included with the sTag as long as the entire string is valid HTML. You should do this if you wish to include the NAME attribute at run time on objects created with the createElement method.

A name attribute? Of course I want it to have a name attribute, it's a form input. The sTag mentioned is the single param passed to createElement -- which according to the W3C DOM spec is supposed to be "the name of the element type to instantiate" (e.g., createElement('input')). And the IE docs are talking about passing HTML in that param?

So, apparently, the only way to assign a name attribute to an input element with DOM in IE is to pass HTML strings to the createElement method instead of just the element type. Wow, serious points for being weird and hackish!

That explained all the code I saw being offered up as the solution for this problem -- creepy-looking stuff like this:

var radio2 =  document.createElement(
    "<input type='radio' name='foo' checked>");

I was trying to remember why this had never bitten me in the ass before, and I remembered that the last time I did any low-level work with dynamic forms was probably implementing the Curriculum-creation tool for the KnowledgeWire app.

That was back in the day when I did tons of stuff with innerHTML -- but Mozilla didn't handle it well for form elements (the opposite of IE, naturally). If you rewrote parts of a form with innerHTML in Mozilla it would do weird stuff like add things to the elements collection, but not remove them.

So I had this whole library of functions for doing dynamic form elements with -- you got it -- innerHTML for IE, and DOM for Mozilla. Kind of makes me a little misty-eyed, thinking of the good ol' days of doing everything twice. It worked perfectly for us (it's probably still in use there), and I never touched the innards of it after that.

And now of course now, trying to do the opposite -- make IE's flaky DOM methods for form inputs work -- I was scratching my head trying to come up with something that didn't involve branching code and using innerHTML, or even fouler, passing HTML markup into createElement.

Well, mercifully, as it turns out, in IE6 (which is what we support in Scooby) inputs created with DOM methods automatically get a name attribute that matches the id. This is reasonable for things like text inputs, but vaguely retarded for radio buttons in that the id for each DOM element is supposed to be unique, and a cluster of radio buttons should all have the same name to make them behave as a unit. But you can at least hold your nose and make that work -- by giving all the form elements in the group -- sigh -- the same id.

What's worse, doing something like creating a whole separate code branch to work around the nasty, false, tricksy DOM methods in IE? Or giving a cluster of radio buttons a common id when the id should be unique? At this point, it's kind of a wash -- both options are equally crappy. I picked the one that didn't require forking the code.

IE is like the sterotypical drunk relative at Christmas time -- he's horrible and irritating, he's not going anywhere, and you can't ignore him.


This is the blog for Matthew Eernisse. I currently work at Yammer as a developer, working mostly with JavaScript. All opinions expressed here are my own, not my employer's.


Previous posts

All previous posts ยป

This blog is a GeddyJS application.