tags:

views:

51

answers:

2

Ok here is my HTML (One row of about 20)

<tr class="post-unauth message-unread">
  <td>
    <input class="check-read" type="checkbox" checked="checked" value="68"/>
  </td>
  <td class="message-description" title="Post Title">
  </td>
  <td class="message-author">Name</td>
  <td class="message-dates">3 hours ago</td>
  <td class="message-commentcount" title="0 comment(s)">
  </td>
</tr>

Now when the checkbox is clicked I need to change the class of the parent

$('.check-read').click(function() {
         $(this).parent().parent().removeClass('message-unread').addClass('message-read');
});

I'm missing somthing obvious I think as this doesnt work (Doesnt error) but nothing changes.

I even tried setting the CSS background color and no change to the HTML.

Any suggestions?

+5  A: 

I think you should try closest. This is new in jQuery 1.3

$(this).closest("tr").removeClass('message-unread').addClass('message-read');

closest docs

As Mark mentions in the comment below, using a class would be more suitable here since it is less likely to be affected by changes in your table structure.

 $(this).closest(".message_row").removeClass('message-unread').addClass('message-read');

And then add "message_row" to your tr. If an unchecked box is guaranteed to have message-unread class then you can use it for your selector instead of adding a message_row class and selecting on it.

sberry2A
I was typing that up as your answer came in. closest is really convenient in cases like this. I would try to use a class instead of the tag since changes in the market are less fragile to the jQuery that way.
Mark
Agree with the class suggestion... I will add that as well.
sberry2A
I like this idea and this works pretty good here, but will this still works if in future they adds new <td> before the checkbox? I mean still the closest returns that tr or the following tr? My Idea/Suggestion would be relate the tr and the checkbox with some id prefix and depending on that find the element which will be some what fool prrof for future DOM changes.
Teja Kantamneni
+1  A: 

Just to offer an alternative solution. In cases like this, I prefer to attach the click to the TR and then let the click event of all the child elements bubble up to the TR. You could do something like this:

$(".classForEachPost").click(function(e){
    var $target = $(e.target);
    var $this = $(this);

    if($target.is(".check-read:checkbox")){
       $this.removeClass("message-unread").addClass("message-read");
    }

    // check for other click events in the TR you might want to act upon
});

I like this pattern when there are a lot of actions in a row, div, etc. It stops a lot of traversing up and down the graph and centralizes all the event handles in one place. It makes it a lot easier for me to wrap that in a jQuery plugin.

$.fn.myPostRow = function(){
    this.click(function(e){
        // same code as above
    }
};

Then you have a plugin for the entire row that you could just call like:

$(".tableOfPosts TR").myPostRow();

This would be the only JavaScript mixed in with the HTML markup and the plugin can be moved to a JS file.

The answer completely digressed from your initial question, but hopefully it is still useful.

Mark