Dynamically Adding Option Elements to Select Objects… The Real Story

I don’t normally blog about pure code subjects, so this is going to be way too technical/boring for the general readership of this blog. However, I wasn’t able to find the definitive answer to this question after searching around with Google, so I figured I’d contribute a little. This is also a wiki-style reminder to myself the next time I need to do this.

Mostly you’ll be interested in this post if you’re trying to programmatically add options to a select list using JavaScript. Of all the ways to do this, there are a few that work and many that don’t. The catch seems to be that IE is picky about how and when the data “inside” the option tag (the visible text in the option list) is set. According to the documentation there should be any number of ways to set this–.text, .innerHTML, .innerText. Of those, the only one that seems to be broadly compatible is .text. .innerText is IE-only, so it’s right out. .innerHTML is valid across platforms, but it messes with the object model in IE6 and IE7 (and IE8 beta 1, now that I look) in such a way that if you use it, you have to add the option element to the select element before setting the .innerHTML property. See below for a breakdown of the methods, plus test code. Blogger might break this, so be sure to look at the plain test page (“view source” is going to be a lot friendlier on that page as well).

In any case, here’s the take-away when adding options to select elements:

  • Always use the .text property of the newly-created option object to set the visible text for the option.
  • As a precaution, add the new option object to the select object’s options collection before setting other properties of the option.

create option, set .value, set .text, add to options list (generally compatible)


function createSetTextAddOption(selectEl,val,displayText) {
var o = document.createElement("OPTION");
o.value = val;
o.text = displayText;
selectEl.options.add(o);
return false;
}


create option, set .value, set .innerHTML, add to options list (fails IE6, IE7, IE8-‘invalid argument’)


function createSetInnerHTMLAddOption(selectEl,val,displayText) {
var o = document.createElement("OPTION");
o.value = val;
o.innerHTML = displayText;
selectEl.options.add(o);
return false;
}


create option, add option to list, set .value, set .innerHTML (generally compatible)


function createAddOptionSetInnerHTML(selectEl,val,displayText) {
var o = document.createElement("OPTION");
o.value = val;
selectEl.options.add(o);
o.innerHTML = displayText;
return false;
}


create option, add option to list, set .value, set .text (generally compatible)


function createAddOptionSetText(selectEl,val,displayText) {
var o = document.createElement("OPTION");
o.value = val;
selectEl.options.add(o);
o.text = displayText;
return false;
}


Attempt to add new options/selects inline (option 2 and select 2 fail in IE, either silently or with the “invalid argument” error)

According to the Microsoft documentation, this shouldn’t work at all. Here’s what they say about the option.add() method:

This method can be used to add elements only after the page loads.

If the method is applied inline, a run-time error occurs.

And yet, it mostly does work, aside from the innerHTML limitation…


// generally compatible inline adds
createSetTextAddOption(document.getElementById('sel5'),'1','added value 1');
createAddOptionSetInnerHTML(document.getElementById('sel5'),'3','added value 3');
createAddOptionSetText(document.getElementById('sel5'),'4','added value 4');

addNewSelect(document.getElementById('sel5'),'1','added value 1',createSetTextAddOption);
addNewSelect(document.getElementById('sel5'),'1','added value 3',createAddOptionSetInnerHTML);
addNewSelect(document.getElementById('sel5'),'1','added value 4',createAddOptionSetText);

// these two fail in IE6, IE7, IE8
createSetInnerHTMLAddOption(document.getElementById('sel5'),'2','added value 2');
addNewSelect(document.getElementById('sel5'),'1','added value 2',createSetInnerHTMLAddOption);

Again, I encourage you to view the plain test page to avoid any Blogger-induced weirdness.

2 thoughts on “Dynamically Adding Option Elements to Select Objects… The Real Story”

  1. Hi there.

    The ability to use .innerHTML on select lists is unfortunately a well known bug.

    *If* you don’t have event handlers registered on the select element, setting HTMLSelectElement.outterHTML = YourFullOutterHTMLString;
    does work quite well, and is very fast when dealing with a 250+ option list.

    Otherwise your solution, or using the new Option(); syntax is required.

    This bug is documented/tracked over at Web Bug Track as ID:274
    http://webbugtrack.blogspot.com/2007/08/bug-274-dom-methods-on-select-lists.html

  2. Thanks Josh! For my implementation I really needed a pure-object approach, and I try to avoid the whole adding DOM objects through innerHTML/outerHTML thing in general because of the possibility of DOM pollution/destruction you mention.

    This is definitely a known bug–even to me!–but Google wasn’t coughing up the definitive answer in my cursory searches (wish it had turned up webbugtrack), so I figured I’d weigh in.

    Thanks again for the comment.

Leave a Reply

Your email address will not be published. Required fields are marked *