views:

4990

answers:

5

I've got a page with a variable number of <select> elements (which explains why I'm using event delegation here). When the user changes the selected option, I want to hide/show different content areas on the page. Here's the code I have:

$(document).ready(function() {
  $('#container').change(function(e) {
    var changed = $(e.target);

    if (changed.is('select[name="mySelectName"]')) {
      // Test the selected option and hide/show different content areas.
    }
  });
});

This works in Firefox and Safari, but in IE the change event doesn't fire. Anyone know why? Thanks!

A: 

I'm trying to understand why you need to double check the name of the select after receiving an event to it.

Do you by any chance have multiple elements with the same id ?

Did you actually mean to say "#container select" instead of "#container" ?

Maciek
No. I'm using event delegation because I don't want to attach the event to every single <select> on the page because there's the potential for dozens of them. By attaching it to the container, there's only a single attachment.
Justin Stayton
And there are other <select> elements on the page that I don't want this event to fire on.
Justin Stayton
You can add an ID to the select element itself
fudgey
+1  A: 

Idea that might help:

$(document).ready(function() {
  $('#container select[name="mySelectName"]').change(function(e) {
    var s = $(e.target);
    if (s.val()=='1') //hide/show something;
  });
});

If you are using AJAX, try live() function:

 $(document).ready(function() {
       $('#container select[name="mySelectName"]').live('change', function(e) {
        var s = $(e.target);
        if (s.val()=='1') //hide/show something;
      });
    });
Arnis L.
`jQuery/live()` does not support the `change` event. See http://docs.jquery.com/Events/live#typefn
Crescent Fresh
@crescentfresh That's something new to me, thanks.
Arnis L.
1.4 supports change event for .live, but the event itself is still a mess in IE as far as I can tell.
Thumbkin
+1  A: 

If I recall correctly you will need to call blur() to have jQuery invoke change() on IE machines. Try something like:

$("select[name=mySelectName]").click(function() {
    $(this).blur();
});
Daniel
Unfortunately, this doesn't do the trick. The event still isn't fired, even when the <select> is blurred.
Justin Stayton
+10  A: 

The change event does not bubble in IE (See here and here). You cannot use event delegation in tandem with it. In fact, it is because of this IE bug that jQuery live had to officially exclude change from the list of supported events (FYI the DOM spec states change should bubble).

You will need to bind directly to each select:

$('#container select').change(/*...*/)

If you really want event delegation you might find some success trying what this person did and bind to click in IE only, which does bubble:

$('#container').bind($.browser.msie ? 'click' : 'change', function(event) {
    /* test event.type and event.target 
     * to capture only select control changes
     */
})

But this browser detection feels really wrong. I'd really try working with the former example (binding directly to the drop downs). Unless you have hundreds of <select> boxes, event delegation wouldn't buy you much here anyway.

Crescent Fresh
Very informative, thanks for your help.
xenon
This would be one of the cases you can't get away from browser testing since you can't really feature test. However, for a full solution, you'd have to also handle keyup for keyboard navigation
Juan Mendes
@Juan: some think feature detecting a bubbling event is possible. See http://perfectionkills.com/detecting-event-support-without-browser-sniffing/#comment-44332
Crescent Fresh
That's cool, thanks. Overview of the link that is applicable here: The post is about detecting supported events. By checking for a 'change' event on a div, you'll know whether the change event bubbles, since a div doesn't have its own change event.
Juan Mendes
A: 

Add this lines to your page head, Sit back and relax! :)

$(document).ready(function(){$('select').bind('onChange',function(){$(this).blur()});});
Soheil