Muffinresearch Labs by Stuart Colville

Bug when creating select options using innerHTML in IE | Comments (18)

Posted in Code on 19th July 2006, 2:12 pm by Stuart

Recently I was creating some code that dynamically changes the options in a select element. In the first draft I decided to us innerHTML for speed. Using innerHTML for this is very straight forward. You build your string of options and dump them into the select.

    var opts;
    for(prop in objData[val]) {
        opts += ‘<option value=”‘+prop+’”>’+objData[val][prop]+’</option>’;
    }
    objTargetSelect.innerHTML = opts;

Unfortunately the draw back to doing this with innerHTML that there is a bug in IE where the first option element gets truncated rendering the select blank.

There’s more on this problem and some potential workarounds involving outerHTML and DOM methods here at support.microsoft.com.

Personally I would recommend using the DOM methods to do this sort of thing rather than resorting to an outerHTML kludge. As you would be producing the options based on a loop the code can be quite concise. See my next post JSON Selects for more on how to use the DOM methods to do this.

Post Tools

Comments: Add yours

1. On July 19th, 2006 at 2:44 pm Chris Heilmann said:

There is also the new Option() constructor in JavaScript for that kind of stuff. However, DOM is the cat’s PJs when it comes to adding a function at the beginning. I showcased all the options you have with err… options in the code example of Chapter 7 of my book.

2. On July 19th, 2006 at 5:28 pm Aaron Bassett said:

I was just working on a project today which required me to generate some select options with Javascript.

I found a combination of innerHTML and the DOM provided me with the best solution. innerHTML was only used to clear the current selects as I did not want to append the newly generated ones on to the end of any options which were already there….eg:

function updateProductSelect(brand) {
	var sel = document.getElementById("productSelect");
	var opt = "";
	var opt_txt = "";
	sel.innerHTML = "";
	var regEx = new RegExp(brand, "gi");
	for(var i = 0; i < listMenuItems.length; i++) {
			if(regEx.test(listMenuItems[i]) == true) {
				opt = document.createElement(”option”);
				opt_txt = document.createTextNode(listMenuItems[i]);
				opt.appendChild(opt_txt);
				opt.setAttribute(”value”, listMenuItemsURLS[i]);
				sel.appendChild(opt);
			}
		}
	sel.disabled = false;
}

I could have used a while loop and removeChild to clear current options..but as you mentioned speed is a factor sometimes ;)

3. On July 19th, 2006 at 8:02 pm Stuart Colville said:

@Chris: Great examples in your link.

@Aaron: Thanks Aaron. If you check out the JSON selects post I’ve done almost the same way, except I did use a loop to remove options. As Christian points out in his comment, using innerHTML to clear the options could be a better bet for performance.

4. On July 21st, 2006 at 9:57 pm Neil Crosby said:

I came across my own particular IE select box annoyance a few months back when I was trying to create a select box that had size using the DOM. In the end I found that the only way I could do everything I wanted to was to use Option().

5. On August 15th, 2006 at 5:54 pm Ryan said:

I have been successful using options.outerHTML when adding to a select box for Internet Explorer.

6. On August 15th, 2006 at 8:40 pm Stuart Colville said:

@Ryan: outerHTML is one way of doing it, but IMHO it’s better still if you can use one method which works for more than one browser.

7. On August 29th, 2006 at 3:16 pm GavrocheLeGnou said:

Hi,
I came to the exact same problem, and there is a quick “workaround” :


objTargetSelect.innerHTML = opts;
if(document.all) { // Or any IE testing
   objTargetSelect.outerHTML = objTargetSelect.outerHTML;
}

That’s right, setting the SELECT’s outerHTML to the value of the SELECT’s outerHTML :p

it’s not really pretty, but it seems that it reloads the select box with all the needed information(id, name, …) and the updated options.

8. On August 29th, 2006 at 3:20 pm Stuart Colville said:

@GavrocheLeGnou: Hehe IE is great! That’s an interesting solution. I’m interested to know, how did you come across this was it by chance?

9. On November 8th, 2006 at 3:59 pm Bram said:

@GavrocheLeGnou:
This wont work… The first OPTION-element gets truncated (as said in the original article) so although it seems it works (no errors, filled options) you’re missing your first OPTION.

10. On November 14th, 2006 at 12:52 pm dan said:

A 7 yr old bug. The IE team is not lazy, as claimed by some ignorant people - they are just incompetent. Microsoft should stop browser development and instead focus on securing their not-surprisingly buggy OS.

11. On January 26th, 2007 at 7:45 pm Alan said:

The quick workaround posted above will work with just a little bit more of a hack.

if(document.all)
{
opts = '<option>truncatethis</option>' + opts;
}
objTargetSelect.innerHTML = opts;
if(document.all) { // Or any IE testing
objTargetSelect.outerHTML = objTargetSelect.outerHTML;
}

Pretty cheesy to have to do something like this, but it works

12. On May 4th, 2007 at 12:02 pm zig said:

I have used the outerHTML-trick and i am having problems with the options[n].selected-property. It seem to be unassigned.

It doesn’t seem as if that property is properly refreshed.

13. On October 5th, 2007 at 9:37 pm LongStone said:

I finally tried the “paste over” for outerHTML worked in this instance…this is after trying normal DOM methods (IE won’t render at all), used it before (create all my elements with DOM compliant code then extract all the HTML for an IE cludge)

tried:
document.createElement(HTMLString); then append -> parent.appendChild(newChild);
then adding inputOption = new Option(vars)
(IE sets first element as selected, can’t change it via element.selected or element.defaultSelected )

not sure if this is consistant (like anything is in IE except errors)

If you want IE to render the HTML properly for display purposes use innerHTML

If you want IE to be able to access the new element in the DOM (like $() or getElementByID) use
document.createElement(HTMLString); then append -> parent.appendChild(newChild); BTW, you’ll have to do this for all your sub elements too :-/

remember with the above method IE will only accept the outer element, ie if HTMLString =

ONLY the select will be out put

Dan, re. “The IE team is not lazy…they are just incompetent” They should be gang raped by a pack of rabid baboons. Time for a class action lawsuit and bill back to M$ for all the wasted time doing work arounds lol.

14. On November 6th, 2007 at 7:01 pm George said:

There is a big problem with selectBox.outerHTML = selectBox.outerHTML;

Any DOM-added event handlers associated with the control (via $addHandler()) will be wiped out.

Yes, this sucks.

15. On January 15th, 2008 at 6:41 pm Ralph said:

As noted by most, there isn’t one nice clean solution other than using the Option() constructor.

The bug is tracked here:
http://webbugtrack.blogspot.com/2007/08/bug-274-dom-methods-on-select-lists.html

But the “best” workaround is not mentioned.

16. On February 1st, 2008 at 7:29 pm James said:

I’ve worked around the problem using the following:
var sourceList = document.getElementByID(”mySelectBox”);
var newInnerHTML = sourceList.parentNode.innerHTML;
var bracketPos = newInnerHTML.indexOf(”>”)+1;
newInnerHTML = newInnerHTML.substring(0, bracketPos)+ SourceOptionsList+ “”;
sourceList.parentNode.innerHTML = newInnerHTML;

I find everything before the first ‘>’, keep that part, and then replace everything after it with my new list of options, and the .

This, of course, will clobber the sourceList variable, as you’re replacing your referenced select object with something completely new.

17. On February 2nd, 2008 at 8:29 pm Stuart Colville said:

@James: I think your last comment (removed) got eaten by something. Feel free to drop me a line and I’ll update your comment.

18. On March 24th, 2008 at 2:54 pm Mrinal said:

I finally found the solution for ‘bug in select option in IE’ specially for the values return by Ajax
the following function will work
function setText(xmlHttp.responseText)
{
var resText=xmlHttp.responseText;
document.getElementbyId(”select_element”).innerHTML=”"+resText;
document.getElementbyId(”select_element”).outerHTML=document.getElementbyId(”select_element”).outerHTML;
}

Here xmlHttp.responseText is the response from ajax funtion which is not shown here.







XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>



Django Admin Ominigraffle Stencil|(0)

Colleague Alex Lee has created a nice stencil for omingraffle with the Django Admin UI components, perfect for wireframing customised admin screens. For more details and to download the stencil see Alex’s Blog csensedesign.co.uk

Scrolling issue in Leopard cured with PRAM reset|(0)

Having got a shiny new MacBook Pro to work on at my new workplace I’ve had a couple of strange problems with Leopard. The main issue was that when scrolling the graphics was suffering what appeared to be a strange redraw problem when scrolling. After googling I found this post:“Distorted graphics in Leopard when scrolling”.

Fortunately for me: resetting the PRAM has worked and the flickering issue has gone for now.

Photos on Flickr

© Copyright 2004-08 Stuart Colville, all rights reserved. May contain traces of Muffin. Powered by WordPress. Hosting by 1&1 This page was baked in 1.125s.