Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
AHAH/AJAX bindings do not work in Internet Explorer for elements of type checkbox or radio. They work fine in all other browsers I tested.
This bug also exists in Drupal 6.
How to recreate the bug: Create a checkbox and add #ajax behavior to it. Demonstrate correct behavior visiting the page with firefox (click the checkbox, it fires the AJAX/AHAH behavior). Visit in IE, and see that it doesn't. The attached demo module can be used for testing.
The attached simple module can be used to demonstrate the behavior.
Comment | File | Size | Author |
---|---|---|---|
#65 | drupal.ajax_checkbox_557284_D7_65.patch | 972 bytes | lathan |
#62 | drupal.ajax_checkbox_557284_D7_61.patch | 927 bytes | lathan |
#49 | drupal.ajax_checkbox_557284_49.patch | 964 bytes | rfay |
#42 | 557284-click-event-42.patch | 1.05 KB | ksenzee |
#42 | 557284-click-event-with-rollback-42.patch | 1.63 KB | ksenzee |
Comments
Comment #1
rfayReturning to this issue
Comment #2
Dave KopecekWorking through the same issue in D6. Found this:
http://opensourcery.com/blog/chad-granum/ie-onchange-events
It's a hack, but It might help.
Comment #3
tanoshimi CreditAttribution: tanoshimi commentedJust come across this thread and can confirm that I'm facing this issue too.
For the benefit of anybody searching, the problem is that, in IE, the [#ajax] callback assigned to a checkbox does not fire until focus of that element is lost - i.e. you click off the checkbox again.
You can recreate this easily using the "AJAX Example: generate textfields" example from the "Examples for Developers" module (www.drupal.org/project/examples).
The example in question has a checkbox form element as follows:
Checking the checkbox "Ask me for my first name" results in no action (no throbber, nothing) in Internet Exporer. Clicking off the checkbox (onto another form element, or just onto an empty bit of page) causes the callback to fire.
However, I also find that callbacks can be lost if, for example, you check checkbox1, and then check checkbox2 (thereby causing callback1 to fire), callback2 never fires, even after you then click off checkbox2.
This pretty much kills the possibility of currently using AJAX checkboxes (although other form elements such as select boxes are unaffected)
Comment #4
rfayI just tested and #states works fine with checkbox-triggered events in IE7.
So this is probably just something we can do differently and it will come out OK.
Comment #5
timos CreditAttribution: timos commentedHi,
Here a tar with the Chad's hack rewritten in a little module. Just download it in your module folder and enable it. The bug is fixed in IE 7 and i think IE6 and IE8 too, but i still have to test.
I just took the original Chad's code and added in the js file a condition if(Drupal.jsEnabled){} and create module and info files to quick implementation in a drupal 6 installation.
Comment #6
rfayHi @timos! Thanks for your work on this. Would you mind experimenting with fixing ajax.js and posting a patch? If you're unfamiliar with patches, see http://drupal.org/patch. I'm *eager* to see this fixed.
Comment #7
casey CreditAttribution: casey commentedI think reason of this issue being fixed is that since jQuery 1.4 "change" and "submit" events are being normalized (http://api.jquery.com/change/)
Comment #8
timos CreditAttribution: timos commentedHi
@rfay sorry i didn't mind this issue is about drupal 7 ! The micro module i posted is a drupal 6.x version. I would be glad to work a (very very) little bit on the drupal 7 version, so i can try to do a patch for it, and for the ahah.js file in the 6th version (i didn't find ajax.js file in the misc repository for the 6th)
But, i can't do it before monday. So on monday evening i try it and i send news here.
Sorry for my froggy english ;-) !
Ok, sorry again, we are on monday evening and a i didn't manage to find out only one minut to do it ! Actually, i'm really unfamiliar with patch, but i thk i can do it. Just give me time (four day more...)
Comment #9
timos CreditAttribution: timos commentedHi,
Ok, here a first patch. To be honest, i just make a diff and patch. I did not any test (no time, and i don't have virtual box ready at home, only linux and no IE to test).
So i can't promise anything about it.
If you want you can test it and maybe improve it...
I test soon
Bye
Comment #10
rfaytimos, thanks for your efforts on this. It still needs some things.
1. We're working with Drupal 7 here, so you'll be patching ajax.js, not ahah.js. It would be nice to get this fixed on D6 as well, but we'll do D7 first.
2. Patches are created from the project root. Your patch included /var/www/... One should be able to go to the Drupal root and apply the patch using
patch -p0 <path/to/patchfile.patch
. See http://drupal.org/patch.3. Please don't upload a patch that you haven't tested.
4. When you post a patch, set the status to "needs review" so the testbot can test it.
Thanks very much for your effort!
-Randy
Comment #11
timos CreditAttribution: timos commentedOk,
Sorry for mistakes,
Do you want i remove the patch until i can test it ?
Comment #12
rfayNo problem, timos, and your contribution is welcome.
Just post a D7 patch here after reviewing #10.
Thanks,
-Randy
Comment #13
rfayInterestingly, the behavior on this has changed over time.
Now, in the "generate textboxes" example alluded to in #3, clicking the checkboxes fires the AJAX event, and the fieldset is rebuilt. The only problem is that the checkbox doesn't *stay* checked, so when you rebuild it again, its state is forgotten.
@timos, still looking forward to your valued contribution.
Comment #14
timos CreditAttribution: timos commentedHi,
sorry for the long time without news and work. I try something those week end.
Cheers
Timos
Comment #15
timos CreditAttribution: timos commentedHum,
I tried to do the job on d7, but i'm a litte bit surpised... the example module doesn't work even in firefox ! So i can't really test it. I'm not aware about the d7 API, so i can't find out why it doesn't work....
I'm sorry but i think my contrib will be limited on a tricky hack for D6.
thought this problem, i try to add the js lines to the ajax.js file and it seems it doesnt' do anything. I can see that as i test the module in ie too, and found the same behavior you note : the checkbox never stay checked even after a click (in my case the ajax event is not fired, but is not fired in firefox too - maybe the alpha 5 release change something...).
I try with and without the trick i mentioned above, but the behavior is always the same...
Maybe if you can explain why the ajax event never fire in the example module given in the description issue, i can test again...
Cheers
Timos
Comment #16
timos CreditAttribution: timos commentedOk, i tried with the example ajax module, and well, ajax event are fired but now i can say the hack whom i talked doesn't work anymore...
Comment #17
rfayI haven't fully finished studying this one, but I suspect this one-line patch is what's required. I was unable to find problems with this. (Submits don't seem to submit inappropriately, which was the thing I expected.)
I haven't finished studying this, but just wanted to mention that this simple change makes the checkbox behavior sane.
What's going on is that on IE the "mark the checkbox as checked" behavior is only done if everybody returns true. Never happens if we return false.
Comment #18
sbrattla CreditAttribution: sbrattla commentedI can confirm that this patch worked for me. I had the excact same problem with MSIE not updating checkbox states when used in conjunction with #states.
I'm using alpha-6, so this issue is still occuring. Would be great if this patch could be applied.
Comment #19
aspilicious CreditAttribution: aspilicious commentedConfirming that it works...
Quickfix after all...
Comment #20
ksenzeeI'm not sure it makes sense to return true from an event handler, where before we were returning false, without also paying attention to whether we want to prevent the default event and stop event propagation (both of which happen automatically when you return false). This will be the click handler for ajax links, for example, and we don't want the default event on those. Maybe we need conditionals to check what kind of event we're handling.
Comment #21
rfay@ksenzee, we are doing exactly that, *allowing* the default event, which includes (in IE) actually updating the checkbox in this case.
That said, your concern is the same as mine: Are there hidden side-effects of this? One approach to this would be to return true only for non-button elements. I'm relatively sure that would be safe.
It's actually baffled me that I haven't found anything wrong with this in manual testing. I expected it to break #ajax-enabled submit buttons, since they must stop processing after submitting to avoid the browser submitting again. But testing with the submit example in the AJAX Example in Examples project doesn't show that problem.
Comment #22
ksenzeeRight, that's exactly my point - allowing the default event in all cases is dangerous. Or at least it should be dangerous. It does seem odd that the submit buttons aren't breaking. I'll try to find time to step through and see if I can figure out why.
Comment #23
RobLoachWhat if we had a
element_settings.return_value
?Then for the checkboxes, we would pass element_settings.return_value = true.... Might be overkill, but hey.
Comment #24
rfayOK, this isn't as fancy as RobLoach's suggestion, but the code is very clear. It just checks to see if it's radio/checkbox and does the return true in that case. It works, anyway.
Comment #25
rfayAnybody approve/disapprove of this?
Comment #26
ksenzeeIt looks good to me. It might be fixing a symptom rather than a root cause, but since none of us can find a root cause, we should definitely fix the symptom.
Comment #27
sunGiven #647228: Links are needlessly unable to fully participate in D7 AJAX framework features, this.type will fail if this is not an INPUT element. Let's make sure it is one.
I wonder whether we shouldn't reverse this condition -- returning false actually only makes sense for buttons (forms) and links...?
Powered by Dreditor.
Comment #28
sbrattla CreditAttribution: sbrattla commentedAre you saying that the propsed patch will fail at some point as 'this' might represent a link? If that is the case, could we just add another check like the one below?
This issue still exists in Drupal 7 (beta 3), so it's probably a good idea to get this one done :-)
Comment #29
sbrattla CreditAttribution: sbrattla commentedComment #30
rfayOh my goodness. Lost track of this. We need to get this in.
@sun, I wasn't fully able to understand your objection in #27. Could you provide a patch and let's get this in.
Comment #31
rfayOK, the code had moved around quite a lot, but here's a patch which does exactly the same thing.
Per sun's request in #27, tested to make sure that element.type was a safe reference.
@sun, #27:
The intent here was to be as gentle as possible. I *would* be interested in you elaborating more about why returning false only makes sense for buttons and links. I'd appreciate if you'd point me to a reference on this, because I'd sure like to know more about this little corner of javascript.
Comment #32
rfayOK, so many of you may not have seen this bug in action because you don't use IE.
Here is a screencast showing the effects of this bug and explaining what it's about and how it affects IE.
http://screencast-o-matic.com/watch/c6leFpX1p
Comment #33
ksenzeeI did some quick searching and couldn't find a reference with a list of which DOM elements have default actions on click events (which is the little corner of JS in question). Since we're already returning true (i.e. allowing the default action and propagating the event) in most cases, let's continue to do so, and only return false (i.e. prevent the default action and stop event propagation) for elements we know to have problems already. That's the smallest possible change I can think of, which seems appropriate at this point in the cycle.
Comment #34
webchickCommitted to HEAD. Thanks!
Comment #36
effulgentsia CreditAttribution: effulgentsia commentedI discovered this issue while working on #995854: #ajax doesn't work at all if a file element (or enctype => "multipart/form-data") is included in the form. Any chance we can change the logic a bit to this? In line with #23 and a D8 @todo for #27. While not a substantive change, I think it's a little more understandable, and gives modules better capability to customize.
Comment #37
rfayWell this works fine and is certainly way more elegant, so +1 from me.
Now you'll want to apply your elegance to #995122: Textfield with #ajax['keypress'] activates on spacebar as well as enter as well? Something like this would be far better.
Comment #38
rfayI just tested this patch and HEAD with IE9, and IE9 does not bind correctly with checkboxes :-(
So it's probably worth solving that here if we're going to reopen this.
Comment #39
sun@rfay: Can you clarify "does not bind correctly to checkboxes" ?
We should consider to use a property name closer to standards -- isn't this called "bubbles" normally?
Powered by Dreditor.
Comment #40
rfay@sun, you'll have to try it. I didn't state it right; that was an old version of this bug that was stuck in my mind.
The actual results on IE9 are that most checkbox clicks don't trigger AJAX events. Sometimes the second click will, etc.
If you don't have an IE9 instance to work with, I can probably figure out a way to provide one or show you mine.
Comment #41
rfayI have a windows 2008 instance set up for anybody that wants to look at this and doesn't want to go through the pain of upgrading everything and installing ie9.
Hostname: ie9.thefays.us
Connect via: Windows Remote Desktop Connection or Linux Terminal Server Client (or any terminal server client)
I've set up a couple of users; I can give you credentials in IRC
To demonstrate the problem shown here, you can go to
http://drupal7.thefays.us/ajax_example/autotextfields and click the checkboxes . Strange things happen, but they're not right. It's similar to what happened with all IE before #31 went in.
Comment #42
ksenzeeIt turns out the problem here is how IE handles change events on radios and checkboxes, which I now remember being bitten by in the past. Clearly I repressed the memory. From http://www.quirksmode.org/dom/events/change.html#t04 :
So IE doesn't consider a box as checked until you've checked it *and then* clicked somewhere outside it. This is true up to and including IE9. The workaround is to use the click event instead, which works fine. I'm attaching a patch that does that.
I'm also attaching a version of the patch that rolls back the fix from #31. The point of that code was to special-case change events for radios and checkboxes, and we're no longer binding to those events. So in my opinion the special casing is now unnecessary. I would however like effulgentsia's take on whether the abstraction he proposed would still be useful in other contexts.
Comment #43
sunIs the click event fired when toggling a radio/checkbox with the spacebar?
Powered by Dreditor.
Comment #44
ksenzeeYep: http://www.quirksmode.org/dom/events/click.html#t05
Comment #45
sunNext to manual tests, we need a shorter version, retaining info, of that comment.
It's not clear to me what the first sentence tries to tell me (i.e., _why_ should we ideally fire an AJAX request on change instead of click). It looks like we can drop that entire sentence.
"Unfortunately" can be removed, IE can be shortened, and we don't need to explain the onBlur event.
Lastly, "See ..." should be "@see ..." on a separate line.
Powered by Dreditor.
Comment #46
effulgentsia CreditAttribution: effulgentsia commentedIf not needed to resolve this issue, then I don't think we should add #ajax['allow_default_action'] (or alternate name, see #39) as part of this issue.
However, something we don't have any use-cases in core for, but may have in contrib, is developers setting #ajax['event'] to something explicit, rather than using the defaults in ajax_pre_render_element(). It seems quite possible that in some of these cases, the developer wouldn't want the browser default action for the event prevented. So I think a separate issue for a #ajax['allow_default_action'] setting would make sense. I'll wait until this one is resolved before opening that.
If it's too late to add it for D7, I'm not overly concerned, because a contrib module can deal with it if needed. #36 was intended to remove per-type special casing within the JS code, because I think files like ajax.js and other generic behaviors should stay generic, and use Drupal.settings for customizations. If we can remove that special casing from the JS code without adding any new #ajax properties, great!
Possibly irrelevant for now, as per above, but I'm not sure there's much of a standard here. There's "bubbles", "preventDefault", "stopPropagation", and probably other terms commonly in use. Returning false is the same as calling both event.preventDefault() and event.stopPropagation(), but I think it's the former that we care about more when we do it.
Comment #47
effulgentsia CreditAttribution: effulgentsia commentedAlso, it would be great to get merlinofchaos reviewing issues like this that change what event we're binding to, during the final days of D7 pre-release. Ctools, Views, and Panels are probably some of the biggest users of the AJAX API.
Comment #48
ksenzeemerlinofchaos won't be available for patch review until his son is at least a few days old. This isn't so much an AJAX thing as it is a straight JS event thing. We need a bunch of manual testing.
Comment #49
rfay#42.1 (with the rollback) doesn't seem to work for any version of IE, including 9.
#42.2 (without rollback) solves the issue nicely for IE9. This patch is just ksenzee's #42 (with no rollback), with comment fixups to address sun's comments in #45.
I'm a little sorry to lose effulgentsia's more elegant approach, but this is an appropriate solution at this point in the release cycle. This patch essentially only deals with the IE9 problem.
It works fine for me in FF 3.6 (linux), IE8, and IE9. (Edit: And with Chrome)
Comment #50
effulgentsia CreditAttribution: effulgentsia commentedI dislike the idea of changing from 'change' to 'click', especially for radio, because it means triggering an AJAX request even when the radio doesn't change, and also, because of potential other browser quirks like this one from http://www.quirksmode.org/dom/events/click.html:
Meanwhile, in http://api.jquery.com/change/, there is this claim:
And apparently, based on the fact that this issue was considered fixed, at least for IE6/7/8, up until #38, it seems like jQuery does fix this properly. Perhaps it just fails to correct for IE9, but maybe plans to before IE9 is released. Needs more research.
Some time soon, I will roll up several outstanding AJAX event handling issues into one. When I do that, I will add a link to it here, and possibly mark this one a dupe.[EDIT: never mind. I realized I can't do what I was thinking of without breaking BC, so I'll save it for D8. We should proceed with each remaining issue independently].Comment #51
rfayOh dear. Has to go into D8 first.
Comment #52
RobLoachBleep bloop
Comment #53
boneless CreditAttribution: boneless commentedany chance to get a working patch for D6?
Comment #54
rfay@boneless, I suspect that #557284-17: AHAH/AJAX bindings do not work on checkbox or radio in IE6/7/8 (and now IE9) would work with D6, but the file name is ahah.js instead of ajax.js.
Comment #55
boneless CreditAttribution: boneless commentedUnfortunately it does not (I only applied the patch from #17 to ahah.js).
My test radios field with 'event' => 'click' does trigger the AJAX request but does not keep the selected option. With 'event' =>'change' the field needs to be clicked twice.
Edit: Funnily enough another radios field with "display: inline;" and the selected value being shifted into another variable seems to work fine with 'event' => 'click'. Very confusing...
Comment #56
nod_1 year later, where do we stand?
Comment #57
rfayHmm. I just updated d7.drupalexamples.info to current D7, and I don't see this problem using either IE8 or IE9.
http://d7.drupalexamples.info/examples/ajax_example/autotextfields
The demonstration problem was to visit that page and click "Ask me my first name", and it wouldn't actually show the textfield that it was supposed to show.
Perhaps I lost track of some more subtle thing, but it looks to me like something has changed here. And BTW, I believe this was all resolved for IE7/IE8. I'm just surprised to see it working on IE9.
Comment #58
nod_Well that was easy, thanks for checking :)
There were some changes around JS for radio and checkboxes working on other issues. I guess it just fixed itself, a patch, newer jQuery? who knows :p
Comment #59
rfayJust to be clear... I did not test on D8. Maybe I'll try that later today.
Comment #60
rfayThe simple test with the autotextfields example also works fine on current D8.
Comment #62
lathanThis patch was never ported to D7, here is a roll against D7.
Comment #63
effulgentsia CreditAttribution: effulgentsia commentedHm. How to reconcile that with #57/#58? @jucallme: do you have steps for how to replicate the bug?
Comment #65
lathanArrg, broken patch fixed.
@effulgentsia I have a basic ajax callback on a radio button group, when selecting them in IE they don't fire the callback as described in this thread, once this patch is applied they do.
Comment #66
rfay@jucallme, so that would mean I just messed up the cleanup test. But could you look at #57 and #58 and try the example in question, and see what's the difference (or if I just messed up?)
A quick screencast demonstrating your issue using the autotextfields example would be great.
Comment #77
gapple