views:

4292

answers:

4

I've got an HTML "select" element which I'm updating dynamically with code something like this:

var selector = document.getElementById('selectorId');    
for (var i = 0; i < data.length; ++i)
{
  var opt = document.createElement('option');
  opt.value = data[i].id;
  opt.text = data[i].name;
  selector.appendChild(opt);
}

Works fine in Firefox, but IE7 doesn't resize the list box to fit the new data. If the list box is initially empty (which it is in my case), you can hardly see any of the options I've added. Is there a better way to do this? Or a way to patch it up to work in IE?

A: 

You could try replacing the entire select element from generated html code, or as a hack removing the element from the DOM and readding it.

Joeri Sebrechts
+2  A: 

Set the innerHTML property of the option objects, instead of their text.

var selector = document.getElementById('selectorId');    
for (var i = 0; i < data.length; ++i)
{
  var opt       = document.createElement('option');
  opt.value     = data[i].id;
  opt.innerHTML = data[i].name;
  selector.appendChild(opt);
}

Works on IE6, just tested. Does not break on FF3, so I guess this is it.

(I chose "innerHTML" because this works across browsers. To set the literal text, you have to use "innerText" on IE, and "textContent" on FF, and you probably have to test it elsewhere as well. As long as there are no special characters (&, <, >) in the "name" properties, "innerHTML" will be enough.)

Tomalak
opt.text is a standard property supported by every JavaScript browser back to Netscape somethingancient.0, and has no problem with the special characters. innerHTML is a non-standard IE extension, albeit one picked up by all the more recent browsers. I don't see how this is really a win.
bobince
Try it out and see the difference. Standard or not, it works in the major browsers, and it fixes the particular problem. I pointed out that you also can do it differently.
Tomalak
And speaking of standards: I've seen people doing (and recommending) mind-bogglingly crazy things to get around the fact that the link target attribute has fallen off the standard. It did not make their code *better*, it just made it "valid" against an SGML parser. Yay.
Tomalak
+4  A: 

You don't need to manipulate DOM for this. Try this instead

var selector = document.getElementById('selectorId');  
for (var i = 0; i < data.length; ++i) {
    selector.options[selector.options.length] = new Option(data[i].name, data[i].id);
}
Marko Dumic
How is that *not* manipulating the DOM? :-) But I have to admit, it works flawlessly. +1
Tomalak
I'm referring to document.createElement (that creates arbitrary elements) which you later insert into DOM (appendChild).Anyway, there are different approaches that work for this particular problem.
Marko Dumic
A: 

Set the width of the select box explicitly, using eg. a CSS ‘width’ style, instead of letting the browser guess the width from its contents.

bobince