Bug Tracker

Ticket #2252 (closed bug: fixed)

Opened 7 years ago

Last modified 8 months ago

Setting select value via val() shows error in IE6

Reported by: zaadjis Owned by: flesler
Priority: low Milestone: 1.11
Component: attributes Version: 1.4.4
Keywords: ie6, select, val Cc:
Blocking: Blocked by:

Description

When a select element is filled (dynamicly) with options and then one tries to set a selected option an error is thrown in IE6: "Could not set the selected property. Unspecified error.".

This seems to be some timing issue, because inserting some delay (timeout, alert, etc.) before the val() call, the error doesn't occur.

Attachments

case.html Download (623 bytes) - added by zaadjis 7 years ago.
Test case
ie6-select-bug.diff Download (467 bytes) - added by zaadjis 7 years ago.
Possible patch
selecttest.aspx Download (3.2 KB) - added by erikkallen 5 years ago.
Workaround

Change History

Changed 7 years ago by zaadjis

Test case

Changed 7 years ago by zaadjis

Possible patch

comment:1 Changed 7 years ago by dalangalma

I tried your patch, and while it works for me using your test case, it still core-dumps the browser on my app. I'll try to distill mine into a minimal test case at some point, but it'll be difficult. The function that's killing things looks like this:

// select is a DOM element, versions is an array of strings, selectedOption is a string
function fillSelect(select, versions, selectedOption) {
    // Map each version string to a DOM element
    var newOptions = $.map(versions, function(version, i) {
        return $("<option></option>")
            .val(version)
            .text(version)
            .get(0);
    });

    $(select).append($(newOptions))
             .val(selectedOption);
}

I'm not sure if it matters, but my page is in "quirks" mode.

comment:2 Changed 6 years ago by flesler

  • Owner set to flesler
  • Status changed from new to assigned
  • Milestone changed from 1.2.3 to 1.2.4

I really don't get this.

You do .val(2) and there's no option with value="2". Don't you mean $('select').attr('selectedIndex',2) ?

That will surely work with the modified recently .attr().

If that was the case, please close the ticket as invalid.

comment:3 Changed 6 years ago by flesler

  • Status changed from assigned to closed
  • Resolution set to invalid
  • Milestone changed from 1.2.4 to 1.3

Ok, the previous comment was wrong. IMO, if a delay is need for a specific case, then you need to provide it yourself. There's no need to delay every call to value, and doing that, would partially ruin the behavior for the rest.

So.. if necessary, you'll need to add a delay yourself.

comment:4 Changed 6 years ago by dalangalma

  • Status changed from closed to reopened
  • Resolution invalid deleted

Here's a super-minimal repro (it doesn't even use jQuery, but explains where the bug in IE6 is):

 http://brh.numbera.com/experiments/browserdemos/ie6-adding-options.html

This shows that accessing the .childNodes property of a select element after adding new options to it, then setting the .selected property of one of the added options, will cause an error in IE6. Since .val() loops through childNodes before it sets .selected on one of the elements, it will always trigger this bug when used to select newly-appended options. zaadjis was simply pointing out that if you put the .selected in a setTimeout, the error won't occur, probably because IE needs to have control handed back to the browser for it to do some internal re-balancing.

I'm not sure how this could be fixed in general, but it is the sort of browser bug that I like jQuery to isolate me from.

comment:5 Changed 6 years ago by dalangalma

Hm, actually, I found that if you wrap setting selected in a try/catch and then throw away the exception, the option gets selected just fine. Maybe that's something to try.

Also, I tried doing: $(select).setAttribute('selectedIndex', 2) using jQuery 1.2.6, and all I got was "Error: Object doesn't support this property or method", which doesn't help.

comment:6 Changed 6 years ago by dalangalma

OK, trying zaadjis' patch works too - if you never touch selected and instead use option.setAttribute('selected', true), there's no error. Seems like his patch is the best bet.

I also realized I had made a mistake in my last post trying to use setAttribute instead of attr. However, that still fails due to a closely related IE6 bug that I noticed which prevents you from setting selectedIndex to the index of any newly created option. It doesn't throw an error, it just doesn't work.

comment:7 Changed 6 years ago by serhii

I've tried the setAttribute and try/catch patches and there is a problem: If I query the value just after being set, it still shows the old value.

After an alert or timeout the value is correctly refreshed.

comment:9 Changed 5 years ago by yehuda

  • Status changed from reopened to closed
  • Resolution set to worksforme

I added the following test and it does not fail in IE:

jQuery("#select1").append("<option value='4'>four</option>"); jQuery("#select1").val(valueObj( 4 )); equals( jQuery("#select1").val(), "4", "Should be possible to set the val() to a newly created option" );

I'm assuming this bug is resolved. If you can still reproduce, please open with more details.

comment:10 Changed 5 years ago by daxx909

  • Status changed from closed to reopened
  • Resolution worksforme deleted

This bug only manifests in IE6, on combination with execution at the "ready" event.

Example code:


<html> <head>

<script type="text/javascript" src="jquery-1.3.2.js"></script> <script type="text/javascript">

$(document).ready(function(){

init(); (A)

});

function init() {

$("#select1").append("<option value='3'>three</option>"); $("#select1").append("<option value='4'>four</option>"); $("#select1").append("<option value='5'>five</option>"); $("#select1").val(4);

alert("Should be 4: "+$("#select1").val());

}

</script> </head> <body>

<select id="select1"></select> <script type="text/javascript">

init(); (B)

</script>

</body> </html>


In the situation above, an exception ("Invalid index") will occur in jQuery-1.3.2.js, line 471:


jQuery( "option", this ).each(function(){

this.selected = (jQuery.inArray( this.value, values ) >= 0

jQuery.inArray( this.text, values ) >= 0);

});


When commenting line (A), and uncommenting line (B) in the example above, the code works correctly in IE6. But the "ready"-event is kind of essential for other stuff...

Changed 5 years ago by erikkallen

Workaround

comment:11 Changed 5 years ago by erikkallen

Please see my proposed fix. It seems to work well for single-select boxes. You can see that if you remove the redefinition of val(), things don't work, but no errors occur with my definition.

It uses the following interesting behaviours:

1) Changing the selectedIndex property (almost) works. It gets changed, but it is not shown as changed in the UI. However, the correct value is returned.

2) Trying to read the val() directly after doing the selectedIndex trick doesn't work. However, it is possible to use the selectedIndex as an index into the children() collection.

3) When IE has had a chance to do some idle stuff, the UI will update correctly in response to a selectedIndex change. Hence the call to window.setTimeout() (which will be a no-op if the bug didn't happen).

comment:12 Changed 4 years ago by snover

  • Status changed from reopened to closed
  • Component changed from core to attributes
  • Priority changed from trivial to low
  • Version changed from 1.2.2 to 1.4.4
  • Milestone 1.3 deleted
  • Keywords val added; val() removed
  • Resolution set to patchwelcome

If someone can come up with a good patch for this, then we’ll take a look at it. Otherwise, since it is fixed in IE7+ and only occurs at the start of a page in IE6, it seems to me like there are more important battles to fight.

comment:13 Changed 3 years ago by anonymous

This IE6 problem does not just occurr when the page loads. It occurs any time you dynamically add options then try to select one.

comment:14 Changed 3 years ago by Shivanshu

Thanks a lot for everyone's comment. It helped me a lot.

comment:15 Changed 3 years ago by anonymous

This error still occurs in 1.7.1 and it does not only occur in ready-event but always when the <selection> tag is created dynamically...

so please reopen (with low priority).

comment:16 Changed 2 years ago by anonymous

Experiencing this in 1.6.4

comment:17 Changed 8 months ago by markelog

  • Status changed from closed to reopened
  • Resolution patchwelcome deleted

comment:18 Changed 8 months ago by markelog

  • Status changed from reopened to closed
  • Resolution set to fixed
  • Milestone set to 1.11
Note: See TracTickets for help on using tickets.