md1337
md1337

Reputation: 1450

jQuery change event not firing in IE when releasing mouse outside of multiple select

Ok, it took me a while just to come up with a title for this question.

Let's say you have a multiple select list and you use jQuery to detect the change event. This will work fine under Firefox and IE under normal conditions. But in IE, if you select something in the list, and you don't release the mouse until after your cursor is outside of the select, the event will not be fired. Doing that works in Firefox.

HTML:

<select size="4" name="ListBox" multiple="multiple" id="ListBox">
    <option value="32">32</option>
    <option value="48">48</option>
</select>

Javascript:

$(ListBox).change(function ()
{
    alert("Change fired");
});

You can test the example here: http://jsfiddle.net/as7EN/1/

FF 3.6.12: WORKS
IE8: DOESN'T WORK

Thanks for any suggestion.

Upvotes: 2

Views: 1529

Answers (2)

md1337
md1337

Reputation: 1450

Turns out it's a jQuery 1.4.* bug!

I tested the Fiddle again with an earlier version of jQuery, 1.3.2, and sure enough it works!

I posted a bug report at jQuery's, please vote up my report there if you'd like them to fix it (very small arrows above the ticket next to the "Previous Ticket" link):

http://bugs.jquery.com/ticket/7698

Upvotes: 2

Raynos
Raynos

Reputation: 169383

A hackish solution

[Edited solution]

var clickDown = false;
var currentlySelected = null;

$("#ListBox").mousedown(function (event)
{
    clickDown = this;
});

$(document).mouseup(function () {
    setTimeout(function() {
        if (clickDown) {
            if (currentlySelected != clickDown.selectedIndex) {
                alert("change");
                currentlySelected = clickDown.selectedIndex;  
            }
            clickDown = false; 
        } 
    }, 0);
});

Basically on mouseDown we set a flag saying you click on the listbox.

Then we check every mouseUp in the entire document. We wrap the entire function in a timeout to ensure that IE8 sets the selectedIndex correctly. And if the clickDown flag is set we know that the clickUp came from a listbox. For convience I also store the listbox object in the flag since (object === true) in javascript.

Then we simply check if our variable containing the current index has changed. If so a change occurs and we update that variable to reflect the new index.

Finally we have to set clickDown to false again outer wise other click ups in the document would think there from the listbox.

This involves checking every click up and is by no means an elegant solution

http://jsfiddle.net/as7EN/37/

[Edit] That only fixed it for chrome. Not for IE8. Working on it.

I've narrowed it down to the fact that IE changes the selectedIndex after the mouseUp event is triggered.

This bug can be avoided by wrapping it in a timeOut so that the function gets called after IE8 sets selectedIndex to the real value. I dont care about IE6/7 fix that yourself.

Also if you want multiselect to work tell me and I'll hack that around aswell

Upvotes: 0

Related Questions