131

I'm using jQuery to hide and show elements when a radio button group is altered/clicked. It works fine in browsers like Firefox, but in IE 6 and 7, the action only occurs when the user then clicks somewhere else on the page.

To elaborate, when you load the page, everything looks fine. In Firefox, if you click a radio button, one table row is hidden and the other one is shown immediately. However, in IE 6 and 7, you click the radio button and nothing will happen until you click somewhere on the page. Only then does IE redraw the page, hiding and showing the relevant elements.

Here's the jQuery I'm using:

$(document).ready(function () {
  $(".hiddenOnLoad").hide();

  $("#viewByOrg").change(function () {
    $(".visibleOnLoad").show();
    $(".hiddenOnLoad").hide();
  });

  $("#viewByProduct").change(function () {
    $(".visibleOnLoad").hide();
    $(".hiddenOnLoad").show();
  });
});

Here's the part of the XHTML that it affects. The whole page validates as XHTML 1.0 Strict.

<tr>
  <td>View by:</td>
  <td>
    <p>
      <input type="radio" name="viewBy" id="viewByOrg" value="organisation"
      checked="checked" />Organisation</p>
    <p>
      <input type="radio" name="viewBy" id="viewByProduct" value="product" />Product</p>
  </td>
</tr>
<tr class="visibleOnLoad">
  <td>Organisation:</td>
  <td>
    <select name="organisation" id="organisation" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>
<tr class="hiddenOnLoad">
  <td>Product:</td>
  <td>
    <select name="product" id="product" multiple="multiple" size="10">
      <option value="1">Option 1</option>
      <option value="2">Option 2</option>
    </select>
  </td>
</tr>

If anyone has any ideas why this is happening and how to fix it, they would be very much appreciated!

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
Philip Morton
  • 129,733
  • 38
  • 88
  • 97

20 Answers20

96

Try using .click instead of .change.

Paolo Bergantino
  • 480,997
  • 81
  • 517
  • 436
  • The Click event only works if you change the value using the mouse - if you use the keyboard then click doesn't trigger, but change does. – samjudson Oct 16 '08 at 14:24
  • 3
    @samjudson, in my testing this is not correct and jquery's click does trigger when i select the next radio button using arrow keys. (vista, ie7) – svandragt Nov 07 '08 at 13:51
  • 1
    @Pacifika: Not for me in IE7. At least it gets that right. "click" is a totally different event from "change" and there are at least some cases (if not all) where it's an inappropriate substitute. – Bobby Jack Jul 09 '09 at 11:27
  • 3
    @samjudson: click events on radio buttons and checkboxes also fire when selecting them using the keyboard. Works in all browsers – Philippe Leybaert Jul 09 '09 at 11:40
  • 4
    I stand corrected - that does appear to be the case, however counter-intuitive it might be! – Bobby Jack Jul 09 '09 at 12:26
  • 2
    This seems to be the most popular answer to this particular question but it is not completely correct! `click` differs from `change` in that its eventhandler will also be called when clicking the already selected option whereas `change` does not. [This answer](http://stackoverflow.com/questions/1159046/jquery-change-event-on-an-input-element-any-way-to-retain-previous-value) has an example of how to use jQuery [`.data`](http://api.jquery.com/data/) to compare the old and new values. – Laoujin Sep 14 '12 at 13:13
  • This is NOT the right answer. IE recognize `$.click()`, but it won't work if you change the value of input and click outside. I suggest using .blur(), but I haven't tested it yet. – Andre Figueiredo Jan 31 '14 at 12:37
54

The problem with using the click event instead of change is you get the event if the same radio box is selected (i.e. hasn't actually changed). This can be filtered out if you check that the new value is different than the old. I find this a little annoying.

If you use the change event, you may notice that it will recognize the change after you click on any other element in IE. If you call blur() in the click event, it'll cause the change event to fire (only if the radio boxes actually have a changed).

Here's how I'm doing it:

// This is the hack for IE
if ($.browser.msie) {
  $("#viewByOrg").click(function() {
    this.blur();
    this.focus();
  });
}

$("#viewByOrg").change(function() {
  // Do stuff here
});

Now you can use the change event like normal.

Edit: Added a call to focus() to prevent accessibility issues (see Bobby's comment below).

Mark A. Nicolosi
  • 82,413
  • 11
  • 44
  • 46
  • 2
    That's a very evil hack, because it prevents your users from navigating using the keyboard, because the focus disappears after selecting a radio button. – Philippe Leybaert Jul 09 '09 at 11:35
  • 5
    This is great, but it causes keyboard accessibility problems. Once the blur() event has fired, the radio button is no longer focussed, so moving amongst radio buttons with the keyboard becomes extremely awkward. My current solution is to add a call to "this.focus();" immediately after the blur() statement. – Bobby Jack Jul 09 '09 at 12:23
  • 1
    I think it's the worst solution presented, because of the accessibility problems. – Philippe Leybaert Jul 09 '09 at 12:35
  • 11
    But the accessibility problem can be resolved with a call to focus(). It's at least as good as using click() for everything. – Bobby Jack Jul 09 '09 at 13:06
  • Thanks Bobby, I'll add that to the answer. – Mark A. Nicolosi Jul 10 '09 at 01:08
  • I had this problem early today and I'm going to try this tomorrow. This seems better to me than using 'click'. If I used 'click' then I would be basically implementing the 'change' event myself. Thanks IE for wasting more of my time having to work around you. – delux247 Feb 17 '10 at 03:47
  • It's better than "click" solution. – Moe Sweet Aug 04 '11 at 07:29
  • The call if ($.browser.msie) no longer works with jQuery 1.10 – TheAlbear Oct 08 '13 at 10:23
33

Have you tried IE's onpropertychange event? I dont know if it makes a difference but it's probably worth a try. IE does not trigger the change event when values are updated via JS code but perhaps onpropertychange would work in this instance.

$("#viewByOrg").bind($.browser.msie? 'propertychange': 'change', function(e) {
  e.preventDefault(); // Your code here 
}); 
sth
  • 222,467
  • 53
  • 283
  • 367
Kevin
  • 331
  • 3
  • 2
14

This should work too:

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   $("#viewByOrg, #viewByProduct").bind(($.browser.msie ? "click" : "change"), function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });
});

Thanks Pier. This was very helpful.

6

In IE you must use the click event, in other browsers onchange. Your function could become

$(document).ready(function(){
   $(".hiddenOnLoad").hide();
   var evt = $.browser.msie ? "click" : "change";
   $("#viewByOrg").bind(evt, function () {
                        $(".visibleOnLoad").show();
                        $(".hiddenOnLoad").hide();
                    });

   $("#viewByProduct").bind(evt, function () {
                        $(".visibleOnLoad").hide();
                        $(".hiddenOnLoad").show();
                    });     
});
Pier Luigi
  • 7,871
  • 9
  • 36
  • 46
6

add this plugin

jQuery.fn.radioChange = function(newFn){
    this.bind(jQuery.browser.msie? "click" : "change", newFn);
}

then

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});
dovidweisz
  • 1,215
  • 13
  • 24
4

I had the same issue with input text.

I changed:

$("#myinput").change(function() { "alert('I changed')" });

to

$("#myinput").attr("onChange", "alert('I changed')");

and everything is working fine for me!

sth
  • 222,467
  • 53
  • 283
  • 367
fabrice
  • 247
  • 1
  • 4
  • 14
2

This is a simple way to tell IE to fire the change event when the element is clicked:

if($.browser.msie) {
    $("#viewByOrg").click(function() {
        $(this).change();
    });
}

You could expand this to something more generic to work with more form elements:

if($.browser.msie) {
    $("input, select").click(function() {
        $(this).change();
    });
    $("input, textarea").keyup(function() {
        $(this).change();
    });
}
paul
  • 307
  • 2
  • 4
1

the trick with the click works... but if you want to get the correct state of radio or checkbox you can use this:

(function($) {
    $('input[type=checkbox], input[type=radio]').live('click', function() {
       var $this = $(this);
       setTimeout(function() {
          $this.trigger('changeIE'); 
       }, 10) 
    });
})(jQuery);

$(selector).bind($.browser.msie && $.browser.version <= 8 ? 'changeIE' : 'change', function() {
  // do whatever you want
})
nostop
  • 743
  • 5
  • 9
1

I'm pretty sure this is a known issue with IE. Adding a handler for the onclick event should fix the problem:

$(document).ready(function(){

    $(".hiddenOnLoad").hide();

    $("#viewByOrg").change(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByOrg").click(function () {
        $(".visibleOnLoad").show();
        $(".hiddenOnLoad").hide();
    });

    $("#viewByProduct").change(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     

    $("#viewByProduct").click(function () {
        $(".visibleOnLoad").hide();
        $(".hiddenOnLoad").show();
    });     
});
Chris Zwiryk
  • 1,321
  • 9
  • 9
1

In IE, force radio and checkboxes to trigger a "change" event:

if($.browser.msie && $.browser.version < 8)
  $('input[type=radio],[type=checkbox]').live('click', function(){
    $(this).trigger('change');
  });
sth
  • 222,467
  • 53
  • 283
  • 367
Jeoff Wilks
  • 363
  • 3
  • 7
1

as of jquery 1.6 this is no longer a problem.. not sure when it was fixed though.. Thank god for it though

Baz1nga
  • 15,485
  • 3
  • 35
  • 61
1

If you change your jQuery version to 1.5.1, you won't have to adjust your code. Then IE9 wil listen just perfect to:

$(SELECTOR).change(function() {
    // Shizzle
});

http://code.jquery.com/jquery-1.5.1.min.js

Bas Matthee
  • 116
  • 7
0

imo using click instead of change makes the ie behaviour be different. I'd rather emulate the change event behaviour using a timer (setTimout).

something like (warning - notepad code):

if ($.browser.msie) {
  var interval = 50;
  var changeHack = 'change-hac';
  var select = $("#viewByOrg");
  select.data(changeHack) = select.val();
  var checkVal=function() {
    var oldVal = select.data(changeHack);
    var newVal = select.val();
    if (oldVal !== newVal) {
      select.data(changeHack, newVal);
      select.trigger('change')
    }
    setTimeout(changeHack, interval);
  }
  setTimeout(changeHack, interval);
}

$("#viewByOrg").change(function() {
  // Do stuff here
});
Ken Egozi
  • 1,825
  • 11
  • 14
0

Try the following:

.bind($.browser.msie ? 'click' : 'change', function(event) {
Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
0

Avoid using .focus() or .select() before .change() function of jquery for IE, then it works fine, im using it in my site.

Thanks

muhammadanish
  • 437
  • 2
  • 6
  • 20
0

try this, it works for me

$("#viewByOrg")
        .attr('onChange', $.browser.msie ? "$(this).data('onChange').apply(this)" : "")
        .change( function(){if(!$.browser.msie)$(this).data('onChange').apply(this)} )
        .data('onChange',function(){alert('put your codes here')});
RainChen
  • 531
  • 4
  • 10
0

Please try with using each instead of change / click, which is working fine even first time in IE as well as other browsers

Not Working a first time

$("#checkboxid").**change**(function () {

});

Working fine even first time

$("#checkboxid").**each**(function () {

});
Vojtech Ruzicka
  • 16,384
  • 15
  • 63
  • 66
0

This may help someone: Instead of starting with the form's id, target the select id and submit the form on change, like this:

<form id='filterIt' action='' method='post'>
  <select id='val' name='val'>
    <option value='1'>One</option>
    <option value='2'>Two</option>
    <option value='6'>Six</option>
  </select>
  <input type="submit" value="go" />
</form>

and the jQuery:

$('#val').change(function(){
  $('#filterIt').submit();
});

(Obviously, the submit button is optional, in case javascript is disabled)

Mayur Birari
  • 5,837
  • 8
  • 34
  • 61
0
//global
var prev_value = ""; 

$(document).ready(function () {

 if (jQuery.browser.msie && $.browser.version < 8)
      $('input:not(:submit):not(:button):not(:hidden), select, textarea').bind("focus", function () { 
         prev_value = $(this).val();

       }).bind("blur", function () { 
         if($(this).val() != prev_value)
         has_changes = true;
       });
}
Sidius
  • 416
  • 1
  • 5
  • 24
kiev
  • 2,040
  • 9
  • 32
  • 54