Show / hide table rows using Javascript classes

I have a table that expands and collapses, but it gets too confusing to use, and IE and Firefox are not working properly.

So here is the JavaScript code:

function toggle_it(itemID){ // Toggle visibility between none and '' if ((document.getElementById(itemID).style.display == 'none')) { document.getElementById(itemID).style.display = '' event.preventDefault() } else { document.getElementById(itemID).style.display = 'none'; event.preventDefault() } } 

And an HTML example:

 <table> <tr> <td>Product</td> <td>Price</td> <td>Destination</td> <td>Updated on</td> </tr> <tr> <td>Oranges</td> <td>100</td> <td><a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')">+ On Store</a></td> <td>22/10</td> </tr> <tr id="tr1" style="display:none"> <td></td> <td>120</td> <td>City 1</td> <td>22/10</td> </tr> <tr id="tr2" style="display:none"> <td></td> <td>140</td> <td>City 2</td> <td>22/10</td> </tr> <tr> <td>Apples</td> <td>100</td> <td><a href="#" id="toggle" onClick="toggle_it('tr3');toggle_it('tr4')">+ On Store</a></td> <td>22/10</td> </tr> <tr id="tr3" style="display:none"> <td></td> <td>120</td> <td>City 1</td> <td>22/10</td> </tr> <tr id="tr4" style="display:none"> <td></td> <td>140</td> <td>City 2</td> <td>22/10</td> </tr> </table> 

The problem is that I use one ID for each and is very annoying because I want to have many hidden lines for each parent and a large number of parents, so there will be too many identifiers for processing. Both IE and FireFox show only the first hidden line, not the others. I suspect this is happening because I did this by running all the identifiers together. I think it would be better if I used classes instead of identifiers to index hidden strings.

I'm really new to this, so please try to explain it in any way. Also I tried jQuery but couldn't get it.

+10
javascript html-table expand
Nov 05 '13 at 19:20
source share
6 answers

It's hard to understand what you are trying to do with this pattern, but you are actually on the right track when thinking about using classes. I created a JSFiddle to demonstrate a slightly better way (I hope) to do this.

Here's the fiddle: link .

What you do, instead of working with identifiers, you work with classes. Your code example has oranges and apples. I consider them as product categories (since I really don't know what your goal is), with their own identifiers. So, I mark the product <tr> with class="cat1" or class="cat2" .

I also mark links with a simple .toggler class. It is not good practice to have onclick attributes for the elements themselves. You must "link" events to page loading using JavaScript. I am doing this with jQuery.

 $(".toggler").click(function(e){ // you handle the event here }); 

In this format, you attach an event handler to the click event of links with the toggler class. In my code, I add the data-prod-cat attribute to the toggler links to indicate which product lines they should control. (The reason for using the data-* attribute is explained here . For more information, you can use the Google "html5" data attributes.)

In the event handler, I do the following:

 $('.cat'+$(this).attr('data-prod-cat')).toggle(); 

With this code, I'm actually trying to create a selector like $('.cat1') so that I can select strings for a specific category of products and change their visibility. I use $(this).attr('data-prod-cat') to access the data-prod-cat attribute of the link that the user clicks. I use the jQuery toggle function, so I don’t need to write such logic as if visible, then hide element, else make it visible , as in your JS code. jQuery does this. The toggle function does what it says and toggle visibility of the specified element (s).

I hope this was quite explanatory.

+13
Nov 05 '13 at 20:18
source share

Well, one way to do this is to simply put the class in the “parent” rows and remove all ids and inline onclick ids:

 <table id="products"> <thead> <tr> <th>Product</th> <th>Price</th> <th>Destination</th> <th>Updated on</th> </tr> </thead> <tbody> <tr class="parent"> <td>Oranges</td> <td>100</td> <td><a href="#">+ On Store</a></td> <td>22/10</td> </tr> <tr> <td></td> <td>120</td> <td>City 1</td> <td>22/10</td> </tr> <tr> <td></td> <td>140</td> <td>City 2</td> <td>22/10</td> </tr> ...etc. </tbody> </table> 

And then you have CSS that hides all non-parents:

 tbody tr { display : none; // default is hidden } tr.parent { display : table-row; // parents are shown } tr.open { display : table-row; // class to be given to "open" child rows } 

This greatly simplifies your html. Note that I added <thead> and <tbody> to your markup to make it easier to hide data lines and ignore header lines.

With jQuery, you can simply do this:

 // when an anchor in the table is clicked $("#products").on("click","a",function(e) { // prevent default behaviour e.preventDefault(); // find all the following TR elements up to the next "parent" // and toggle their "open" class $(this).closest("tr").nextUntil(".parent").toggleClass("open"); }); 

Demo: http://jsfiddle.net/CBLWS/1/

Or, to implement something like this in plain JavaScript, maybe something like the following:

 document.getElementById("products").addEventListener("click", function(e) { // if clicked item is an anchor if (e.target.tagName === "A") { e.preventDefault(); // get reference to anchor parent TR var row = e.target.parentNode.parentNode; // loop through all of the following TRs until the next parent is found while ((row = nextTr(row)) && !/\bparent\b/.test(row.className)) toggle_it(row); } }); function nextTr(row) { // find next sibling that is an element (skip text nodes, etc.) while ((row = row.nextSibling) && row.nodeType != 1); return row; } function toggle_it(item){ if (/\bopen\b/.test(item.className)) // if item already has the class item.className = item.className.replace(/\bopen\b/," "); // remove it else // otherwise item.className += " open"; // add it } 

Demo: http://jsfiddle.net/CBLWS/

In any case, put JavaScript in the <script> element, which is located at the end of the body, so that it runs after the table has been parsed.

+4
Nov 05 '13 at 20:19
source share

JQuery 10.1.2 has a nice show and hides features that encapsulate the behavior you're talking about. This saves you from having to write a new function or keep track of css classes.

 $("tr1").show(); $("tr1").hide(); 

w3cSchool show and hide jQuery link

+3
Feb 07 '14 at 16:02
source share
 event.preventDefault() 

It does not work in all browsers. Instead, you can return false in the OnClick event.

 onClick="toggle_it('tr1');toggle_it('tr2'); return false;"> 

Not sure if this is the best way, but I tested in IE, FF and Chrome and worked great.

+2
Nov 05 '13 at 20:23
source share

Below is my Script, which shows / hides the table row with the identifier "agent".

 <script type="text/javascript"> function showhiderow() { if (document.getElementById("<%=RadioButton1.ClientID %>").checked == true) { document.getElementById("agencyrow").style.display = ''; } else { document.getElementById("agencyrow").style.display = 'none'; } } </script> 

Just call the showhiderow() function on an showhiderow() radio onClick

+1
Sep 09 '15 at 8:22
source share

AngularJS directives ng-show, ng-hide allows you to display and hide the line:

  <tr ng-show="rw.isExpanded"> </tr> 

The string will be visible when rw.isExpanded == true and hidden when rw.isExpanded == false. ng-hide does the same thing, but requires the opposite condition.

+1
May 23 '16 at 16:48
source share



All Articles