25

I am using jQuery's toggle() to show/hide table rows. It works fine in FireFox but does not work in IE 8.

.show()/.hide() work fine though.

slideToggle() does not work in IE either - it shows for a split second then disappears again. Works fine in FireFox.

My HTML looks similar to this

<a id="readOnlyRowsToggle">Click</a>  
<table>  
  <tr><td>row</td></tr>  
  <tr><td>row</td></tr>  
  <tr class="readOnlyRow"><td>row</td></tr>  
  <tr class="readOnlyRow"><td>row</td></tr>  
  <tr class="readOnlyRow"><td>row</td></tr>  
</table>

JavaScript

$(document).ready(function() {  
    $(".readOnlyRow").hide();  
    $("#readOnlyRowsToggle").click(function() {  
        $(".readOnlyRow").toggle();  
    });  
});  
Community
  • 1
  • 1
Robert MacLean
  • 38,975
  • 25
  • 98
  • 152

13 Answers13

46

I've experienced this same error on tr's in tables. I did some investigation using IE8's script debugging tool.

First I tried using toggle:

$(classname).toggle();

This works in FF but not IE8.

I then tried this:

if($(classname).is(":visible"))//IE8 always evaluates to true.
     $(classname).hide();
else
     $(classname).show();

When I debugged this code, jquery always thought it was visible. So it would close it but then it would never open it back.

I then changed it to this:

var elem = $(classname)[0];
if(elem.style.display == 'none')
     $(classname).show();
else
{
     $(classname).hide();               
}

That worked fine. jQuery's got a bug in it or maybe my html's a little screwy. Either way, this fixed my issue.

Pavel Chuchuva
  • 22,633
  • 10
  • 99
  • 115
Brian Bolton
  • 3,633
  • 8
  • 35
  • 43
  • Love it. I found this bug also and this suggestion fixed my problem within seconds. Many Thx. – Aaron Jul 22 '09 at 04:35
  • 1
    Thanks dude. Another episode of 'StackOverflow saved my job!' – penderi Aug 05 '09 at 15:54
  • 4
    elem.style.display should be elem.css('display') – Martin Sep 16 '09 at 20:08
  • 2
    It seems like this line: var elem = $(classname)[0]; limits the function to only toggling the first element [0] with that classname. What if you have a few page elements that you want toggled at the same time? How can you get all elements to toggle correctly? – Jen Feb 04 '10 at 17:40
  • @Jen: $(classname)[0] does not only toggle the first element, it just checks if the first of all the selected elements is visible or hidden. Based on that element all selected elements (including the first one) will be shown or hidden. – Jules Colle Aug 18 '10 at 15:15
  • @Martin - that would only work if line 1 was `var elem = $(classname)`. However, the `[0]` retrieves the DOM element to be used rather than the jQuery object. DOM elements don't have a `css()` function, thus your replacement would not work. – Matt Huggins Sep 25 '10 at 20:42
9

Upgrading to jQuery 1.4 fixes this, whilst I'm at it though, the only "fix" on this page which worked for me was Dough boy's answer:

$(document).ready(function() {  
  $(".readOnlyRow").hide();  
  $("#readOnlyRowsToggle").click(function() {  
    $(".readOnlyRow").toggle($('.readOnlyRow').css('display') == 'none');  
  });  
});
Robin Duckett
  • 2,094
  • 3
  • 16
  • 15
  • I've read the docs on jQuery's .toggle()...I still don't get how the toggle code above works. Could you/someone please explain it? – runrig Jun 10 '10 at 23:17
  • Nevermind, I now see the docs for calling with a boolean: .toggle( showOrHide ) – runrig Jun 11 '10 at 20:45
6

Remove the period from your <tr class=".readOnlyRow"><td>row</td></tr>. The syntax for jQuery class selecting is to prepend it with a period, but you don't need it in your HTML code.

Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • 1
    Well spotted, but not the cause unfortunately. That was caused by my retyping into the question. I have fixed it up the question, but the problem still remains. – Robert MacLean Jun 10 '09 at 12:38
  • 1
    Have you tried simply defining some CSS for your .readOnlyRow class with display:none? You could then toggle the CSS class (toggleClass) instead of having jQuery figure out the visibility toggling. – Cᴏʀʏ Jun 10 '09 at 15:10
4

I found that while this does not work in IE8

$('.tableRowToToggle').toggle();

but this does work:

$('.tableRowToToggle').each(function(){this.toggle()});

Got the idea from the link jAST posted here before

4

I fixed this problem by hiding children of the TR element.

toggleTr($(".toggletr"));

function toggleTr(el) {
    $(el).children('td').each(function() {
        $(this).toggle();
    });
}

This seems to be ok for FF3.5/FF3/IE8/IE7/IE6/Chrome/Safari.

JSVS
  • 163
  • 6
3

Just encountered this myself -- the easiest solution I've found is to check for:

:not(:hidden)

instead of

:visible

then act accordingly . .

marclar
  • 3,026
  • 5
  • 35
  • 56
2

Looks like this has been fixed in JQuery 1.4.

Maciej
  • 21
  • 1
2

Tables are an interesting piece of html, they don't follow normal rules as other elements.

basically tables display as tables, there are special rules for tables but this was not dealt with properly in older browsers because of the roller coaster of craziness that was the browser wars.

Essentially in older browsers tables display properties were minimal and the flow was left largely undocumented so instead of altering predefined values for the table/tr/td tag it is best to instead add and remove the following class and simply toggle the class itself on and off on the attribute of the table/tr/td.

.tableHide {
    display: none;
}

<table>
<tr><td> Visible content</td></tr>
<tr><td> Visible content</td> <td class="**tableHide**"> **Hidden Content**</td></tr>
</table>

The reason for this is so that it is a separate class being used to toggle the display therefore nothing on the table itself is being changed nor do any of the tables properties need to be altered, display and any related layout properties are preserved even if the browser doesn't make that easy behind the scenes.

timewaster51
  • 120
  • 5
1
$(document).ready(function() {  
    $(".readOnlyRow").hide();  
    $("#readOnlyRowsToggle").click(function() {  
        $(".readOnlyRow").toggle($('.readOnlyRow').css('display') == 'none');  
    });  
});

There is a jQuery bug that IE8 causes everything to evaluate to true. Try above

1

I had the same issue, but I found a nice workaround to make toggle/slideToggle work in all browsers.

<a id="myButton">Click</a>
<div id="myDiv" display="none">lorem ipsum .... text ....</div>  

and now the JS:

    jQuery("#myButton").click(function () {
  var currentDisplay = jQuery("#myDiv").css("display"); // save the current Display value
  jQuery(#myDiv).slideToggle("fast", function () { // lets do a nice slideToggle
    // this code will run AFTER the sildeToggle is done
    // so if slideToggle worked fine (in FF, chrome, ...) this will have no evect, since the value is already block or none
    // but in case IE 8 runs this script, it will set the css display to the current value
    if (currentDisplay == "none") {
      jQuery(#myDiv).css('display', 'block');
    }else {
      jQuery(#myDiv).css('display', 'none');
        }
    });
    return false;
});

The result is that slideToggle works fine in all Browsers, except for IE8, in which will look a weird (messed up slide), but it will still work.

Ry-
  • 218,210
  • 55
  • 464
  • 476
0

I have noticed that toggle may not work for iphone if you include jquery mobile. If you run toggle (.ready) before jquery mobile is loaded then its fine.

TroodoN-Mike
  • 15,687
  • 15
  • 55
  • 78
-1

because you are having them click an <a>, you need the function to return false.

helloandre
  • 10,541
  • 8
  • 47
  • 64
-1

I've noticed this as well. Likely you'll have to toggle a class on each td instead. Haven't tried this solution yet, so let me know!

For others - this is specific to IE8, not 6 or 7.

EDIT

Clearly you didn't try this as evidenced by the -1, as I just did with fine results (in my situation).

CSS

tr.hideme td { display: none }

JS

$("#view-advanced").click(function() {
    $("tr.hideme td").toggle();
    return false;
});
ScottE
  • 21,530
  • 18
  • 94
  • 131
  • placing toggle() on the td's produces a different result: it toggles some cells and others not, but it is not consistent in what/how it toggles. I suspect there may be a halloween problem occuring when placing it on td's. Interestingly it works fine on FF, and show()/hide() on td's works fine on IE8 & FF. – Robert MacLean Jun 10 '09 at 13:07
  • In my first test I actually removed the class from the tr and put it on the TD, which is where I got the weird results. I have now tried changing it with the way you suggested (excluding CSS) in your edit (i.e. changing the selector) and that selector does not work in either FF or IE8. I also tried the following combinations of selectors and those didn't work either: tr.readOnlyRow > td .readOnlyRow > td .readOnlyRow td I then tried changing the hide function to the CSS and ended up with the same weird issue as before. – Robert MacLean Jun 10 '09 at 15:33
  • Not sure it doesn't work for you - works fine for me in IE6 - 8, FF3, Safari. – ScottE Jun 10 '09 at 16:50
  • Which version of jQuery are you each using? – Cᴏʀʏ Jun 12 '09 at 17:58