IE OnChange events

I have been working on a Drupal project here at OpenSourcery that involves a dynamic form which updates via ajax whenever a radio button or checkbox is modified. Drupal has built-in ajax/ahah, making this task much simpler. It lets you specify which type of event you want to trigger the ajax, as well as many other options.

For this specifically the requirement was that it occur with the 'OnChange' event. This works great in firefox, but not so great in IE. IE does not register an 'OnChange' event until the mouse is clicked somewhere else on the page after having changed your radio/checkbox selection. This is of course not the desired behavior.

Drupal offers other choices for events that trigger the ajax. The next obvious candidate was 'click'. Click provided consistant behavior between IE and FF. When you click the new button the form would update. However, it resulted in some undesirable behavior in both browsers. The radio button selection would not update. The correct option was sent to post for ajax, but the actual radio button selection did not change.

At this point it became obvious that I was going to need to hand-code some javascript to work around this issue. At first I attempted to write javascript that would update the radio selection after the ajax fired. This was an exercise in futility. I encountered many difficulties, most of which were probably due to inexperience.

Before pounding my head too long on my first attempted solution, a better solution reached my brain. Instead of using 'Click' and trying to re-write default radio and checkbox functionality, I would use 'OnChange' and work around IE's problem. The solution was simple, if the browser is IE, add an 'OnClick' event to all the ajax elements that triggers the 'OnChange' event.

This solution worked perfectly, and was very easy to write, even for someone with little js experience. My first time through I failed to follow proper Drupal convention, and as such I had to implement my own logic to update all the element triggers whenever ajax was used. Fortunately Jonathan reviewed my JS and pointed out the proper way to achieve this (see note 2).

Here is the final version of the javascript

Drupal.behaviors.nexusForm = function (context) {
  if (jQuery.browser.msie) {
    trig_bind()
  }
  //Hide the botton we only want to see if the browser does not support js
  $("#edit-continue").hide()
}
 
//IE waits until another event to send the 'change' events on radios and checkboxes
//This bind a trigger for those events on click.
function trig_bind() {
  //unbind old events
  $("input[type='checkbox']").unbind( 'click' )
  $("input[type='radio']").unbind( 'click' )
  //bind the events
  $("input[type='checkbox']").bind( 'click', function() {
    $(this).trigger( 'change' )
  })
  $("input[type='radio']").bind( 'click', function() {
    $(this).trigger( 'change' )
  })
}

Notes:

  1. when I refer to IE I am referring to IE 6.
  2. an even better solution would be to use 'live' from jquery 1.3, however Drupal still uses 1.2, and updating jquery was not an option.

Tagged as: Drupal, IE

13 comments

Visitor (not verified) wrote 2 years 43 weeks ago

ahah.js bug

The reason you can't use checkbox onclick with #ahah isn't because of some browser bug, but because ahah.js always returns false when its event handler is triggered. This is meant to block normal form submissions, but it fires regardless of whether a button was clicked. In this case, it blocks the checkbox value from being changed, exactly as the DOM event model specifies.

dalin (not verified) wrote 2 years 42 weeks ago

Don't forget accessibility.

Don't forget accessibility. If you are using OnClick, that excludes keyboard navigation.

Visitor (not verified) wrote 2 years 34 weeks ago

Only on IE6?

When you refer to IE you mean IE 6?.

On IE7 happens the same. I didn't tried on IE8, but y supose it still happens. Microsoft is very lazy fixing bugs, don't you think the same?

Naresh (not verified) wrote 2 years 34 weeks ago

onchange vs onclick

I am stuck with the onchange vs onclick conflict. Do you have any idea about the following issue:

When you have onchange event on a textbox and also onclick on a button, what should be done if we want that the click event should also fire on button when we change value in textbox and immediately click on the button?

seutje (not verified) wrote 1 year 42 weeks ago

hmmz, I solved this issue by

hmmz, I solved this issue by simply using

$(selector).bind('change click keypress', function() {
  ...
});

instead of just
$(selector).bind('change', function() {
  ...
});

this should catch all non-programmatic ways of marking a checkbox/radio button, even when 1 option of a radio group is selected and then altered with the arrow keys or something

also, this seems to be normalized in jQuery 1.4, so the change event fires properly if ur using this version

seutje (not verified) wrote 1 year 42 weeks ago

(sry for double-posting like

(sry for double-posting like this)

@Naresh: avoid binding click handlers to buttons, there's a million other ways to get the form to submit, for instance: most browsers will submit the form a textfield resides in when the user presses enter while focussed on that field

I therefore use:

$('form').bind('submit', function() {
  // do work
});

instead of

$('form input[type=submit]').bind('click', function() {
  // do work
});

that should catch all ways to submit the form, including a click on the submit button

Timos (not verified) wrote 1 year 38 weeks ago

thanks

Hi
Thanks for this tip !
I implemented in a very little module and i post the tar on the issue post about this problem. I hope you will not be angry about it.
Chers !
Tim

Carl (not verified) wrote 1 year 21 weeks ago

amazing

This solution worked perfectly, and was very easy to write, even for someone with little js experience. My first time through I failed to follow proper Drupal convention brmaswn , and as such I had to implement my own logic to update all the element triggers whenever ajax was used.

Brad Pitcher (not verified) wrote 1 year 19 weeks ago

great solution

Thanks for the tip.

Visitor (not verified) wrote 1 year 13 weeks ago

@seutje

Nice one, worked for me!

Thanks.

Catherine Ellis (not verified) wrote 1 year 12 weeks ago

I bow to your greatness

I'm fairly new to Javascript and just had my first go with the ahah helper module but unfortunately came across this problem too. The above fix worked for me, and I've bookmarked this page for future reference. Just out of interest, would you put the above in a conditional comment for IE? Thanks Catherine

Celio (not verified) wrote 1 year 11 weeks ago

thanks

worked like a charm! thanks!!!

Jacøb (not verified) wrote 50 weeks 2 days ago

Gracias!

Me ahorraste horas de trabajo ;D