views:

43

answers:

3

I have a large table with 27 columns and between 5 to 100 rows. I have mode switch (checkbox) that switches the view of a table from the first 5 columns (simple) to 27 columns (expert) and back.

Currently I use the following jquery method to switch between the modes:

 $("#ToggleTableCells").click(function(){
    if($(this).is(':checked')){
            $(".hiddencells").removeClass("hiddencells").addClass("showcells");
            }else{
            $(".showcells").removeClass("showcells").addClass("hiddencells");
    }
});

If the table has a large number of rows it is getting a while before it toggles. Is there any faster way to replace classes. Or make the above code faster?

Using css gt methode partly works, but toggling back hides all table rows:

$("#toggleTableCells").change(function() {  
                if(this.checked){                   
                $("#Table tr td:gt(4), #Table tr th:gt(4)").show();             
                }else{                      
                $("#Table tr td:gt(4), #Table tr th:gt(4)").hide(); 
                }
    });

The first answer of Nick seems to be the best solution:

$("#ToggleTableCells").change(function(){
    if(this.checked){
        $(".hiddencells").toggleClass("hiddencells showcells");
    }else{
        $(".showcells").toggleClass("showcells hiddencells");
    }
});

Even though I tried combining the answers of Nick and Nikita it did not resulted into a noticeable increase in speed.

final solution:

var cells = $();
$("#Table tr").each(function() { cells = cells.add($(this).children(":gt(4)")); });
$("#ToggleTableCells").change(function(){
cells.toggle(this.checked);
});
+3  A: 

First I'd use change on a checkbox, no need for .is(":checked") just use the DOM .checked property, then more importantly for performance here, use a single .toggleClass() to effectively swap the classes.

$("#ToggleTableCells").change(function(){
  if(this.checked){
    $(".hiddencells").toggleClass("hiddencells showcells");
  }else{
    $(".showcells").toggleClass("showcells hiddencells");
  }
});

Something like toggling them directly may be better though, try it out:

var cells = $();
$("#myTable tr").each(function() { cells = cells.add($(this).children().slice(5)); });
$("#ToggleTableCells").change(function(){ cells.toggle(this.checked); });​

You can test that version here.

Nick Craver
This seems to improve the speed somewhat. Any other options I can try. I tried using css nth-child selector. But it can only hide one column. not 5 > 27.
Plippie
@Plippie - Try the updated second option with a cached selector, should give you a fair speed boost.
Nick Craver
@Nick - well it toggles it off but when toggling back it hides all rows and columns except the first 5 headers.maybe use: var cells = $("#table tr").children();and use the cached cells in the first code?
Plippie
@Plippie - Try this: http://jsfiddle.net/nick_craver/uNHxj/1/
Nick Craver
@Nick nice code example! after innitial toggle it responded very fast. I do not think it can be made faster then this.
Plippie
I have to come back to the cells array solution. It is working fine when you have max 10 rows. If you have more then 20 rows any version of IE will drop a "script is taking a long time error" errorin my table of 200 rows times 18 columns the array function in jqeury source is called 830576 times! However in All other browsers its working fine. But still the "cell" array solution is not the way to go.
Plippie
A: 

Yes, I think you can speed it up by making you class selectors more specific. I.e.,

("#my_table td.hiddencells")

instead of

$(".hiddencells")

Same for another one. Using specific selectors instead of general ones is a well-known jQuery trick to improve performance.

Nikita Rybak
`this` refers to a checkbox, it won't have these as children/descendants.
Nick Craver
it would be like this then: $("td.showclass").toggleClass("showclass hiddenclass"); Problem is: you also have a header <th>
Plippie
@Nick Thanks, changed.
Nikita Rybak
@Plippie There's nothing wrong with _$("td.showclass, th.showclass"))_ If you have a lot of other elements (divs, spans, text nodes, etc), then not making jQuery to go through them all should help.
Nikita Rybak
A: 

I settled with checkbox toggling table cells with class "hiddencolumn".

$("checkbox").change(function() {
    if (this.checked) {
      $(".hiddencolumn").show();
    } else {
      $(".hiddencolumn").hide();
    }
});

It works even with 500 rows. And it is fast.

Plippie