jQuery, .change() notification, and IE
I'd like to know when this radio button changes, ok? What's that, you're not going to tell me when it changes exactly, you're going to tell me the next time an event occurs? Gee, thanks.
Here's the thing. I've got some JavaScript code that's part of an application. When the user changes a radio button, I want to be notified so that I can change other parts of the page. Easy, right?
$(document).ready(function(){
$("input[name='custom-format']:radio").change(function() {
alert("Option changed!");
});
});
(I'm building on top of jQuery 1.3.1; here's a full test case: ietest.zip.)
That works fine in Firefox and Safari and I bet it would work fine in Opera too. Heck, it would probably work fine in Links if JavaScript was supported.
On IE(7)? Not so much.
Changing the radio button causes nothing to happen. Except that if you click anywhere on the page after you've changed the radio button, then you get the popup.
Someone please tell me I'm doing something stupid. Or tell me how to fix the stupid thing IE is doing. Or something.
Comments
http://webbugtrack.blogspot.com/2007/11/bug-193-onchange-does-not-fire-properly.html
"The onchange event can be attached (inline or as an event handler) to any form element. It fires whenever the value of the form field changes. Unfortunately, the behavior is a bit strange in IE, in that for a checkbox, or a radio button field, the event doesn't fire when it is supposed to (right when you click the option you want to choose), but instead it only fires, when you click elsewhere on the page/form, or if you explicitly call blur(); on the field."
I don't know the historical reasons but in IE5->IE8 you're best bet with
<input>
&@type=radio
or@type=checkbox
is to use the click event. I believe it is also possible to use change, if you fire the blur event yourself.If anyone knows the historical reasons for this, I'd love to know... I'm on vacation or I do the list archaeology myself.
just use the click event - same thing
Click is not the same thing. Click fires even if you click on the same radio button. So either I have to accept that that is uncommon enough not to care or I have to track the current state of all the buttons separately.
Not that it looks like I have much choice.
[expletives deleted --ed]
Can you do onclick=this.blur()? (syntax uncertain) This could lead to the right onchange events, if I understand the other comments right.
"Click is not the same thing. Click fires even if you click on the same radio button."
Which is what you want. A click should change/toggle a radio button or checkbox.
No, it isn't what I want. Luckily, it turns out in this application that it's close enough.
Consider three mutually exclusive options A, B, and C represented by a group of radio buttons. Initially A is selected.
I click on B: the radio button changes and both the onClick and onChange events fire.
I click on B again: the radio button doesn't change and the onClick event fires, but the onChange event does not.
Since it's only the change of a radio button that I care about, I'd prefer to hang my code off the onChange event.
Except that in yet another bit of IE buggyness, the onChange event doesn't fire until the focus leaves the button group.
%$#@?!
Just came across this myself in IE8. You'd have thought Microsoft would have fixed this bug by now......
To all those saying "use click, it's the same":
a) It's obviously not the same; it wouldn't exist if it were
b) Using click breaks all UI methods that are NOT moving a mouse pointer over the element and clicking the button. Most significantly, this breaks keyboard accessibility. 'change' has the wonderful property that, in half-decent browsers, it does exactly what it says: fires if the value changes, however that change might occur (e.g. I hope - although haven't tested - that it would also fire if the value was programatically changed)
I thought jQuery was supposed to solve all these horrible cross-browser problems! Do you know if anyone's working on fixing this? It seems as if whatever fix can be applied by all of us (however insufficient that fix might be), can also be applied in the jQuery library, saving us the bother.
Cheers,
- Bobby
Click could be an alternative in some cases but here's a case where click does not apply. I am trying to use Ben Nadel's example of listening for changes in the browser location object -- see Binding Events To Non-DOM Objects With jQuery, and using this to adjust html element classes.
This works nicely in Firefox, Safari, and Chrome, but in IE it only works in the "forward" direction, when changes to the window location (specifically, the hash value) are the result of clicks. When I use the browser's back button, the hash values change, but IE does not execute the function that I have bound to that change.
Now I have to waste another day figuring out a workaround. I hate IE.
Alexander, you saved me hours of endless tweaking with IE! That click handler works just fine.
Thanks.
@Alexander M. Turek Thank you so much for this, as marco has mentioned above, this works perfectly and has saved me *hours* of trouble!
I'm surprised that jQuery doesn't have this feature built into the core, this is certainly one of those cross browser issues that should be addressed by the library.
Another pat on the back for Alexander M. Turek, that kludge did the trick for me.
And a kick in the teeth to the IE team at Microsoft for making us suffer so much.
I also noticed that IE8 (and probably seven) doesn't seem to understand label tags whose content is an image so I'm off to write a click handler for my image labels...
Thanks Alexander! This saved my tail on a huge project :D
Alexander, perfect fix! This seems to be working perfectly in all the IE browsers. Very clever.
Wish I would have found this a few hours ago ;-) Better late than never I guess. Now I can move on to more important things. Alexander's code is perfect!
WOW!!! Well done!!!
Thanks!
Works also well for checkboxes...
Unfortunately, in my case the next checkbox happened to be hidden, so I got an error:
Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus.
Agrgrh!
IE Sucks. Why do we continue trying to waist so much time, money and effort getting things sort of working in this piece of crap. This only causes the world to keep using IE. So that we have to go on supporting IE, so that the world keeps using it, so that ...
Martijn
Thanks, saved my day.
wow, saved me some time there, could not figure out why IE8 would not focus on a post-page load created DOM element (while safari and FF do just fine).
We have a have a multiple choice survey [single page for admins] with @70 multi-checkbox response questions.
Workaround in my case was to focus on the first unchecked checkbox in target group, and then blur() on that element. At this point IE now responds to further event. We then focus on the post-page load created DOM element (positioned above the question text) and remove() it.
No more need to pop an alert in IE in order to get the focus() working.
I concur with everyone here re: the utter piece of trash-edness that is IE...
http://msdn.microsoft.com/en-us/library/ms536912%28VS.85%29.aspx
They seem to think it's not a bug but a feature.
I almost thought Alexander's jQuery solution didn't work...but it's because I was still using the "onclick" event for the radio button. Make sure to use "onchange" in the radio button.
BTW, I understand that Microsoft was trying to be consistent with the other elements. However, this goes to show why I disagree with UI experts who have concrete rules like "strict consistency" and "shortest mouse distance". My #1 rule is that rules should be broken if they don't feel right...and in this case, I can't think of a single use-case for Microsoft's implementation. In every use case I've run into, Microsoft's implementation was just wrong.
That being said, I think Microsoft actually chose a better Box Model. The standard box model makes it impossible to use percentage widths totaling 100% while using fixed pixel paddings (your total width will be 100% plus all of the paddings). Of course CSS3 solves this in two ways: letting us choose the box model, or using expressions. I guess IE is like a broken clock...it's still right twice a day.
Thank goodness for the memory of the Internet!
This issue bit me with jQuery 1.5.1 and IE8.
If you ever see this...THANK YOU, Alex! You saved me boatloads of time.