Dynamically showing and hiding table rows
This is really just a reminder for myself. When using the DOM to dynamically hide and show table elements (like a table row), you can't use display = "block"
to bring a table row back to life in Firefox; although, it works okay in IE. It's best to simply use display = ""
so that Firefox correctly resets it to table-row
and IE can still do what it does.
I imagine other browsers behave similarly to Firefox.
Conversation
In my upcoming update for YTS, I've got a script that dynamically shows/hides rows based on whether JavaScript is enabled.
And this problem drove me absolute nuts when I was building it. Where was this post 2 months ago?
Good call though.
This drove me nuts as well. I was trying to dynamicly hide/display <tr>s dependant on what options the user chose. I ended up adding the following block to my javaScript function:
if(navigator.appName.indexOf("Microsoft") > -1){
var canSee = 'block'
} else {
var canSee = 'table-row';
}
Then I can use the variable 'canSee' instead of 'block' to show hidden <tr>s. <td>s can be hidden by replacing 'table-row' with 'table-cell'.
man, thank you for the tip on hiding/showing tr's in firefox, to mimic IE's laziness :)
it worked perfect!
tony
Another cool use of this I found is with <tbody> tags. Use 'table-row-group' instead of 'table-row' & you can hide/show multiple rows at a time without creating a million document.getElementById() calls.
thank you evan... ill have to try!
Thank you very much!
How about making it compatable with Netscape? Any solutions for that? I am using the display="" and still does not work.
the solution posted on 03/15 will work on for Micorsoft Based (Internet Explorer) or Gecko Based Browsers (Netscape, Mozilla, Firefox...).
As far as rendering the element 'invisible', all you have to do is set the display="none". Hopefully this should help.
Great, i think you, I found this article with Google and it solved my problem with Firefox compatibility!
Man... It's 7AM and I've been banging my head against this for the past 4 hours. I just came across ths article now.
Deceptive little problem cause you don't immediately notice that the working snippets on other peoples' sites are showing/hiding entire tables and not table elements.
I was trying to enclose a row in DIV tags, then hide/show that... but even with Evan's snippet, that didn't work. Finally assigned an ID to the row tag, added the snippet, and got firefox to roll over.
So thanks Evan.... just wish I found this sooner. I'm going to sleep.
Well done Evan et al,
A hard problem to google but its probably down to testing in IE and hoping the rest of the browsers are as lask as IE in renedering cr&p HTML/CSS.
You have saved me hours - once again well done!
Skillsy
xvvxcvcvxcv
Thanks for the helpful note. Sorry about the junk comment above, I was admiring your comment form. =)
great solution - i have been looking for this for months now
Oops :( The solution isn't working for me. I have exactly the same problem i.e. to hide a row or set of rows in a table. I know I am making some mistake but still...
Here is the sample html:
Here is the Javascipt method I used after reading your post:
Javascript call to the method is:
Please tell me what's wrong am I doing. I have already spent hours to find out what you are saying.
I am currently using a bad solution of making separate table with div around it for each row.
I was making the same mistake at first. You need to just stop using DIV's for this. Include an ID attribute inside the TR tags, and go from there. For instance:
>table>
> tr id="toggleRow1">
>   td> content to show/hide   /td>
>   td> content to show/hide   /td>
>/tr>
> tr id="toggleRow2">
>   td> content to show/hide   /td>
>/tr>
>/table>
Only downside is that for you, you now have to show/hide each row individually. They're not grouped by the DIV tags anymore, each row needing its own unique ID. A minor inconvenience though.
Hillel hit it on the head... to to hide multiple groups, <tbody> tags & substitute 'table-row-group' for 'table-row'
- E
Thanks Evan! You're a genius!
good fix thanks
Just wanted to reply to this and with the function that I came up with to hide a table row. I have tested in IE 6 and Firefox 1.5
I had to use this code to hide/show rows in Firefox:
style2.display = iState ? '' : 'none'
And This to hide/show in IE:
style2.display = iState ? 'block' : 'none'
iState is set to 0 to hide and 1 to show.
hi,
I have been rolling now for 2 days in this show/hide kinda stuff. From DIV to iFrame to tBody (learnt right here ;) ) I have given every thing a try. Now this is what I have come up with, this objective is same: Show/Hide table rows.. working perfectly fine on IE, but in Firefox the table formatting is ruining and a bit of space is shown between rows that I really don't want. Here is the example page.
http://ramadan-blessings.com/tab/tr_mania.htm
Any ideas or solution for fixing it... please guide .. thanks
note: I am now using tbody to group rows.
-----------------------------------------------
function showTR(id){
if (document.getElementById && document.createTextNode)
{
var tr=document.getElementById(id);
if (tr) {
if (tr.style.display == 'none') {
// we set style to block for IE
// but for firefox we use table-row
try {
tr.style.display='table-row';
} catch(e) {
tr.style.display = 'block';
}
}
else {
tr.style.display = 'none';
}
}
}
}
----------------------------------------
The root of your problem lies in the use of a Try/Catch. the code you're using won't throw any errors, hence the misrenderings. instead, use the browser detector below:
if(navigator.appName.indexOf("Microsoft") > -1){
var canSee = 'block'
} else {
var canSee = 'table-row';
}
This will determin whether if the end user is using IE or something else (Opera, Firefox, Safari ... ). & then use the approprate code.
Hope this helps.
- Evan
I can't hide multiple rows in IE.
That worked really well. Found it pretty quickly in google too.
Thanks for the fix.
Hiding a row can throw off formatting in FF if rowspan is used in the table.
As in:
<html>
<head>
<style>
.show {}
.hide {display:none}
</style>
<script>
function on(i) { document.getElementById(i).className="show"; }
function off(i){ document.getElementById(i).className="hide"; }
</script>
</head>
<body>
hover the mouse on the table and see the 1st row's test2 box (dis)appear.<br />
In ff, the table will grow forever with each mouse on/out cycle.<br />
<table border=1>
<tr onmouseover='on("more1")' onmouseout='off("more1")'>
<td rowspan=2>left</td>
<td>top right</td>
</tr>
<tr id=more1 class=hide><td>bottom right</td></tr>
<tr class="this extra TR is not required in IE to keep the formatting right"><td></td></tr>
<tr>
<td rowspan=2>left</td>
<td>top right</td>
</tr>
<tr><td>bottom right</td></tr>
</table>
</body>
Any idea how to best counteract this?
Cheers, Chris
sorry about the error, my previous example should use
.show {display:block}
in any case, as mentioned in the page's intro, the problem is corrected when using
.show {display:}
but i still wonder if this is normal behaviour.
Also, pls note the extra TR which is only req'd for FF, not IE, to keep formatting ok when the other TR is hidden.
I've been struggling with this little problem for a while now, maybe somebody here can help...
I am using a recordset to display a set of tables. I am dynamically setting the id of these values to 0, 1 and 2.
I am after an IE solution to show/hide all tables that meet a certain criteria that the use selects from a radial button.
Using the getElementById I can make it show/hide the first table ID that meets the criteria. But I am trying to do it for ALL the tables that have that ID.
I know getElementById will only do it on the first element, so how do I do it for them all?
I'll assume that the tables reside within a <form> field. Name the tables in each grouping with the same name and then call the elements by their name (ie: formName.tableName). Hopefully, this'll resove your issue.
- Evan
Whoa!!! I mispoke on the last posting... (Must drink my coffee before answering my email). Use "document.getElementsByName(tableName)" in lue of formName.tableName. sorry about that.
- Evan
The code I am using is something like this...
function toggleDn(DnRecNo){
if (DnRecNo==0) {
document.form1.tbl_2.style.display = 'none';
document.form1.tbl_0.style.display = 'inline';
}
}
but I am getting is "document.form1.tbl_2.style' is null or not an object.
The table generation is produced by a recordset loop, therefore I will have multiple ID's set to tbl_0 or tbl_2
That was pretty much what I was using before.
When you say the tableName, do you mean the ID? If so, that is pretty much what I have been doing (except not in a form).
This is my test page...
http://sdsl.ganedatascan.com/test.asp
Not the ID, the NAME of the element (<Table cellpadding="0"cellspacing="0" border="0" NAME="tableName">). Multiple elements can use the same name. By using the document.getElementsByName(tableName) function, you can call as many elements as you want, as long as they have the same name & change the display value of it, or what ever else you'd like to alter via the DOM.
- Evan
Evan, awesome tip on using <tbody> to hide show multiple rows.
-Sourabh
Thank you - I was having a hard time getting firefox to display correctly - saved the day!
Thanks heaps for the advice on table-row. I was trying to figure out why firefox was being stupid. You've saved me a lot of hair pulling and wasted time.. Thanks!
Hi Hillel,
This is a great link....I was also struggling the same way..........now its JUST NEAT!!!. Thank you man and all the people who have put postings in this forum....
How can you do a similar thing using CSS only? I am applying styles based on a class on the tr. In this case I want to hide all rows except those that are in error:
What do I put into this rule to override the display: none? I can't put "", and display doesn't take auto, normal, or default. Can I just put display: ; ?
I achieved the same thing through IE's conditional comment so that IE gets specific styles that no other browser needs.
And then my default.css that sets the tr to table-row:
And the IE-specific IE.css that sets it to block instead of table-row:
After this change it works in IE6, Opera 9, and FireFox2.
Hi again, it's been a while. I'm wondering if you have any ideas for how to show/hide a row without using the ID attribute. As you probably know, IE has some kind of issue with returning strange results from a getElementByID(), which I've been avoiding by using getElementsByName()[0] instead wherever possible. However table rows don't have a 'name' attribute (at least as far as I know), so that workaround is no good for toggling row visibility. I was praying I would never have to worry about this, but I just came across it: IE returns 'error: object expected' for getElementByID(myrow). Any ideas? And thanks again.
just wanted to say that i was having an issue with IE working fine showing/hiding a few div's but firefox (2.0) would break the layout when showing again, then increasingly add blank space whenever the show/hide fired again.
The display = "" works just great.
This is a nice tip. That saved me quite a bit of time
Evan/Hillel/Sourabh,
Since you have already worked on it, Can either of you please put the function and the corresponding table in code to show as an example. I am using a table within div tag that I need to hide/show, its the div tag I am hiding/showing, and it works for IE, of course, but not in firefox. Code sample would greatly help. Sincere thanks.
WOW!!!! saved my precious hair on my almost bald pate.
Thanks
Thank-You! Couldn't figure out why it wasn't working.!
wonderful fix , its so insane to see that we all as consumers of technology need to keep fixing bugs with these so called big shot companies who think they have invented the next big thing.....
Stumbled on this article today, and wow, what a big help. I was trying for about an hour to use a DIV to hide a table row but it was just frustrating me.
I built a function that may be of some help to you. It works with both TR and table groupings (TBODY). If no second argument is passed to it it simply tries to reverse it's current state (so if it's hidden it will show it, if it's visible it will hide it). If the second argument is specified as TRUE it will show it, if it's specified as FALSE it will hide it. Pretty straight-forward, seems to work in both Internet Explorer and Firefox well.
<textarea cols="60" rows="8">function ToggleTableRow ( id ) { var obj = document.getElementById(id); var state = (arguments.length >= 2 && typeof(arguments[1]) == "boolean" ? arguments[1] : (obj.style.display.length && obj.style.display.toLowerCase() != "none" ? false : true)); if (obj) obj.style.display = (state ? (navigator.appName.indexOf("Microsoft") >= 0 ? "block" : (obj.nodeName && obj.nodeName.toLowerCase() == "tbody" ? "table-row-group" : "table-row")) : "none"); }</textarea>
This worked for me. When you hide the table row, the table shrinks and when you show the row the table grows. I successfully tested it in both FireFox 2 and IE 7.
Here's my JavaScript:
Here's some html to test it with:
<table>
<tr id="testrow">
<td>my caption</td>
<td><input id="testinput"></td>
</tr>
<tr>
<td align="center" colspan="2">
<button type="button" onClick="hideShowHTMLItem('testrow', 0);">Hide</button>
<button type="button" onClick="hideShowHTMLItem('testrow', 1);">Show</button>
</td>
</tr>
</table>
You can of course implement this into "adding" rows to a table. Say for if you would like to add upload fields etc. or just extra information fields this can be easily done with just making a big table with all the information extras, maybe 20-30 fields that are hidden and add a javascript link/button that executes a snippet of code that changes the class of the rows that are hidden.
var currentFieldNumber = 2
function addOneField()
{
document.getElementById('rowField' + currentFieldNumber).className="show";
document.getElementById('linkAdder' + (currentFieldNumber-1)).className="hide";
noAddressFields++;
if (currentFieldNumber == N)
{
document.getElementById('linkAdderN').className="hide";
}
}
+
for instance...
great help though, thanks alot
@ Post 37 from Someguy51
----------------
Awesome post, but is there a way to apply this to multiple table rows with a single click?
Okay, never mind, I found a way to do it just by using <tbody> tags around the rows and referencing the tbody id.
Thanks for the help.
Thanks, this thread solved the getting Firefox and IE table rows to disappear and appear correctly. Something I'd spent lots of time on my own not solving.
Go to this url for a cool solution
http://www.clearwaterclinical.com/cwc/example_code/dynamic_tables.html
I'm having a problem with IE 6/7 that when I show/hide rows that have the rowspan attribute. When I show the rows, then the header columns' widths lose their widths and seem to double in width. When I hide the rows, they go back to the correct widths. Anybody have any clue about this issue?
Genius!
Thanks again!
Phil
I am having problem making a tablerow visible using Javascript. The Javascript code that i am using is something like this:-
In the TableData i am adding the following attribute:-
onclick="toggle(this);"
It's not working..what could be the reason?