Thursday, October 14, 2010

Cloned SELECT elements in IE

What I love about IE browsers is that genuine feeling of moral superiority that you unavoidable accumulate inside yourself when you're dealing with its features. Found one more "treasure" that killed half of my day.

The story goes like that. Say I have a SELECT element and then you clone it a bunch of times and populate with new content, kinda like that

var original = document.createElement('select');
clone = original.cloneNode(false);
document.body.appendChild(clone);

$(clone).html('<option>boo hoo!</option>');

And that all works fine, but now say you update the content in another function, say an ajax callback or something

var original = document.createElement('select');
clone = original.cloneNode(false);
document.body.appendChild(clone);

setTimeout(function() {
$(clone).html('<option>boo hoo!</option>');
}, 0);

You would expect that this is no different from the first example and here is where they will get ya. Not only it does not update the options list (it will be empty), but it also somehow manages to show you that the innerHTML property was actually updated and contains all the new data.


// .....

setTimeout(function() {
$(clone).html('<option>boo hoo!</option>');
alert(clone.innerHTML); // -> '<option>boo hoo!</option>'
}, 0);

All versions affected 6,7 and 8 (didn't test in 9 though)

In case you really really need to update a cloned SELECT element in an async callback, here is a hack how you can do that


// ....
setTimeout(function() {
$(clone).html('<option>boo hoo!</option>');

var dummy = document.createElement('option');
dummy.text = 'dummy'; // DON'T use innerHTML in here!
clone.add(dummy);
clone.removeChild(dummy);
}, 0);

It will fix the problem, but you'll need to add some checks in there to ensure it's actually IE you're dealing with.

That's the whole gotcha. Hope will save someone's day

No comments: