Now watch carefully:function addNewOption(select, value, label) {
var option = document.createElement("option");
option.setAttribute("value", value);
option.appendChild(document.createTextNode(label));
select.appendChild(option);
}
function getOptionIdx(select, value) {
if(!select.options) return -1;
for(var oNum = 0; oNum != select.options.length; oNum++) {
if(select.options[oNum].value == value) return oNum;
}
return -1;
}
var optVal = "1";
var select = $("exampleSelect"); //prototype shortcut
addNewOption(select, optVal, "one");
This code retrieves a select by ID and adds an option to it. (The select is a single-value select.) The following code selects that option:
select.selectedIndex = getOptionIdx(select, optVal);
Or it would do, if it worked in IE. Apparently selectedIndex is readonly in IE4, which I don't care about. However, selectedIndex is also readonly in IE6, under certain circumstances, but it just fails silently. The workaround for the IE4 bug was as follows:
select.options[getOptionIdx(select, optVal)].selected = true;
This fails in IE6 with the stunningly unhelpful message "Could not set the selected property. Unspecified error."
HOWEVER, this code does work:
var optIdx = getOptionIdx(select, optVal);
alert("optIdx="+optIdx);
select.options[optIdx].selected = true; // [1]
Removing the alert (or logging statement or whatever) gets you straight back to square one. Wierder still, surrounding [1] with a try-catch block will throw an "undefined" error, and set the select to the value, which I guess is the workaround I need.
Needless to say, I don't have this problem on FireFox. My completely uneducated guess is that DOM tree operations are slightly asynchronous, and that the time it took for the JS interpreter to move onto the next instruction was longer than the time it took for the DOM update thread to finish making changes, when computers were slower than they are now. I have no idea.
This workaround may be for some who found this post by searching for a solution to this problem (I didn't find one so I had to come up with this myself).
ReplyDeleteThe problem was appearing for me in an onLoad call, might be the same with a call from embedded script I suspect. I noted also that an alert() with the code would make it work so I figured that maybe it's a problem with the page loading procedure and interrputing that helps.. So why not break out of the onLoad?
My solution is to put a setTimeout() call to my option setting function in the function called by onLoad. So it now looks like: setTimeout("initSelections()", 100); with function initSelections() {} doing the select.selectedIndex = X; and working properly.
100ms is fine for me, I suspect it could go lower and still be fine.
IE is awful.
ReplyDeleteI encountered this problem during work, and since I had to fix multiple select boxes the setTimeout solution wasn't working for me, as the pointer for the option already changed by the time it executed the script.
Anyways, here is a fix that actually worked for IE. instead of using
ele.selected = true;
I used
ele.setAttribute('selected',true);
And it actually worked.
Conclusion: If I spent as much time writing real code at work instead of fixing IE-specific bugs, you would have all known me by now.
I'm struggling with this bug right now (I'm trying to set a [select] to a default value on [body onload]). I've tried all of the suggested solutions, but none of them work.
ReplyDeleteAnnoyingly, IE refuses to recognize the options property of my select element - it keeps saying that it's null or not an object. This remains true even if I use the window.setTimeout() method to delay execution by 500ms.
I really, really hate IE6. Thanks for the post, though - it's at least given me somewhere to start.
Do the following:
ReplyDeletewhile(true) try { option.selected = true; break; } catch(e) {}
It solves this stupid MSIE bug (a kind of synchronization/locked variable error)
Thanks for your insights
Jose M. Arranz
A finer solution:
ReplyDeleteif (option.selected != myValue)
while(true) try { option.selected = myValue; break; } catch(e) {}
Otherwise could enter in an infinite loop.
Jose M. Arranz
JNIEasy: C/C++ meets Java
This is really a GREAT help, thanks a lot .!
ReplyDeleteThis was of great help. Using setAttribute works like a charm! Thanks a lot
ReplyDeleteThanks a lot, a whole wasted afternoon was ended by this article
ReplyDeleteThanks a lot, it solved my problem.
ReplyDeleteGreat bit of info for selecting multiple options in internet explorer
ReplyDeletegreat help... I found this useful
ReplyDeletethanks
Great help.. Thanks
ReplyDeleteThanks. This save my life.
ReplyDeletethe option tag requires a value attribute in IE. Simply set the value to the same value that is between the option tags and you're set.
ReplyDeleteie (no pun intended)
select
option value="Blue">Blue option
option value="Red">Red option
select
(Sorry, blogger doesn't allow full tags)
Then IE can access it with JavaScript by element.value.
Thanks for posting this. Keep up the good work!
ReplyDeletethanks this worked for me-
ReplyDeletetry { dropdown.selectedIndex = i; } catch (e) { };
My select code was in one of the functions called onLoad as well but I didnt need to try the setTimeOut option though that has worked for me before when I am manipulating the DOM from a function within onLoad on IE
ok it didnt work as i specified above. that only works when i do Ctrl+F5
ReplyDeletehad to use the recursive stuff-
if (dropdown.options[i].selected != true) while (true) try { dropdown.options[i].selected = true; break; } catch (e) { }
I feel sad :(