Philip Morton
Philip Morton

Reputation: 131879

Getting jQuery to recognise .change() in IE

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!

Upvotes: 131

Views: 94122

Answers (20)

Dayanand Rupanavar
Dayanand Rupanavar

Reputation: 1

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 () {

});

Upvotes: 0

kiev
kiev

Reputation: 2070

//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;
       });
}

Upvotes: 0

muhammadanish
muhammadanish

Reputation: 455

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

Thanks

Upvotes: 0

Bilal Jalil
Bilal Jalil

Reputation: 31

Try the following:

.bind($.browser.msie ? 'click' : 'change', function(event) {

Upvotes: 0

Jongosi
Jongosi

Reputation: 1

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)

Upvotes: 0

nostop
nostop

Reputation: 1023

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
})

Upvotes: 1

Paolo Bergantino
Paolo Bergantino

Reputation: 488384

Try using .click instead of .change.

Upvotes: 96

Bas Matthee
Bas Matthee

Reputation: 116

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

Upvotes: 1

Baz1nga
Baz1nga

Reputation: 15579

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

Upvotes: 1

fabrice
fabrice

Reputation: 347

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!

Upvotes: 4

Jeoff Wilks
Jeoff Wilks

Reputation: 363

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');
  });

Upvotes: 1

dovidweisz
dovidweisz

Reputation: 1234

add this plugin

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

then

$(function(){
    $("radioBtnSelector").radioChange(function(){
        //do stuff
    });
});

Upvotes: 6

RainChen
RainChen

Reputation: 531

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')});

Upvotes: 0

paul
paul

Reputation: 307

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();
    });
}

Upvotes: 2

Kevin
Kevin

Reputation: 331

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 
}); 

Upvotes: 33

Ken Egozi
Ken Egozi

Reputation: 1835

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
});

Upvotes: 0

Mark A. Nicolosi
Mark A. Nicolosi

Reputation: 85561

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).

Upvotes: 54

Arthur Bezner
Arthur Bezner

Reputation:

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.

Upvotes: 14

Pier Luigi
Pier Luigi

Reputation: 7871

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();
                    });     
});

Upvotes: 6

Chris Zwiryk
Chris Zwiryk

Reputation: 1317

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();
    });     
});

Upvotes: 1

Related Questions