tags:

views:

88

answers:

2

Hello, I'm using this in conjunction with the tablesorter plug-in, my goal is to have a blank class attribute in any column that is not being sorted, i.e. when I click one column the class attributes in the others are removed.

I have a table with a whole bunch of headers, basically what I want to be able to do is when I click on a table header, I wanna all other tables to have their css class removed, but the one I'm clicking on should be toggling between two css classes. I'm using a rel tag within an anchor tag in the content of the header, I do this because we're using XHTML Strict and rel can't be defined in the table header tag itself. My code is as follows:

$(function() {
  $("a[rel='Header']").click(function () {

      $("a[rel='Header']").each(function() {
        if($(this).attr("class")=="sort-up"){$(this).removeClass("sort-up");}
        if($(this).attr("class")=="sort-down"){$(this).removeClass("sort-down");}
       })

   if($(this).attr("class")==""){$(this).addClass("sort-up");}
   $(this).toggleClass("sort-down")
      });   
});

What I'm assuming it should be doing is as soon as a header is clicked, cycle through each header, if it contains the class attribute "sort-up", remove it; if it contains the class attribute "sort-down", remove it. Then, for the currently clicked header, add the class attribute "sort-up" and toggle between the "sort-down" attribute. My problem is that when I click on one header, if it's using the "sort-down" class, represented in the header by a down arrow(\/), then I go and click on another header in a different column, the attribute doesn't get removed. It will, however, remove the "sort-up" class (^).
Here is a list of my header in XHTML:

<thead>
   <tr>
    <th><a rel = "Header" href="#" class="">Title</a></th>
    <th><a rel = "Header" href="#" class="">Instructor</a></th>
    <th class="{sorter: 'usLongDate'}"><a rel = "Header" href="#" class="">Date</a></th>
    <th class="{sorter: false}">Start/End</th>
    <th><a rel = "Header" href="#" class="">Seats Available</a></th>
    <th><a rel = "Header" href="#" class="">Enrolled</a></th>
    <th><a rel = "Header" href="#" class="">Pre-Requisites</a></th>
    <th class="{sorter: false}">Workshop Actions</th>
   </tr>
  </thead>

UPDATED with changes recommended by waxwing, stupid mistake, it works, I wasn't paying attention to the syntax of the hasClass. Thanks.

$(function() {
  $("a[rel='Header']").click(function () {

      $("a[rel='Header']").each(function() {
        if($(this).hasClass("sort-up")){$(this).removeClass("sort-up");}
        if($(this).hasClass("sort-down")){$(this).removeClass("sort-down");}
       })

   if($(this).hasClass("")){$(this).addClass("sort-up");}
       if ($(this).hasClass("sort-up")) { 
           $(this).removeClass("sort-up").addClass("sort-down"); 
       } else {
           $(this).removeClass("sort-down").addClass("sort-up");
       }
   if($(this).attr("title") == "Sort column in ascending order"){
    $(this).attr({title : "Sort column in descending order"});}
   else {$(this).attr({title : "Sort column in ascending order"});} 
      });   
});
A: 

It looks like this to me: you click once, and the sort-up class is added since class is empty. Then, the sort-down class is also added, due to the following line. So now you have a cell with both sort-up and sort-down. Clicking on another header, neither

if($(this).attr("class")=="sort-up")

nor

if($(this).attr("class")=="sort-down")

will be true, so the classes will not be removed. If on the other hand, you click twice on the anchor, the first time it will add both classes, and the second time it will actually toggle (remove) the sort-down class. Then when you click another column it works like expected.

I suggest a couple of changes. Instead of using,

if($(this).attr("class")=="sort-up")

you can use,

if ($(this).hasClass("sort-up"))

which will still be true if there are other classes as well. Furthermore, you cannot use toggleClass in this case. Instead use something like,

if ($(this).hasClass("sort-up")) { 
    $(this).removeClass("sort-up").addClass("sort-down"); 
} else {
    $(this).removeClass("sort-down").addClass("sort-up");
}

which should give the anchor the sort-down class on the first click, and then toggle between them sort-up and sort-down on subsequent clicks.

waxwing
Hello waxwing, if ($(this).hasClass("sort-up")) in the .each method, but now when I click on a different heading, it won't remove the class from the other heading. Not sure why, I've posted the updated code above.
kingrichard2005
A: 

Try:

$(function() {
  $("a[rel='Header']").click(function () {
    // store the header and this for later use
    var $thead = $(this).parents().filter("thead").slice(0,1);
    var $this = $(this);

    // if we were sort-up - we become sort-down - otherwise we become sort-up
    if ($this.hasClass('sort-up')) { 
      $this.removeClass('sort-up').addClass('sort-down');
    } else {
      $this.removeClass('sort-down').addClass('sort-up');
    }

    // all headers except the one we clicked on - remove sort classes
    $("a[rel='Header']",$thead).not($this[0]).each(function() {
      $(this).removeClass('sort-up').removeClass('sort-down');
    });

    // set link titles based on current class
    $("a[rel='Header']", $thead).each(function() {
      if ($(this).hasClass('sort-up'))
      {
        $(this).attr('title', 'Sort column in descending order');
      } else {
        $(this).attr('title', 'Sort column in ascending order');
      }
    });
    // end click function
  });
});
gnarf
Thanks gnarf, I'll keep this approach handy as well for future reference.
kingrichard2005