views:

880

answers:

2

I have a table that looks something like this.

<table>
  <thead>
    <tr>
      <th>Foo</th>
      <th>Bar</th>
    </tr>
  </thead>
  <tbody>
    <tr class="data">
      <td>Info here</th>
      <td><a href"/url_here" class="edit">Edit</a></td>
    </tr>
    <tr class="data">
      <td>More here</th>
      <td><a href"/url_here" class="edit">Edit</a></td>
    </tr>
  </tbody>
</table>

I want to show the Edit link when you mouse over any of the rows inside of the . I have tried a few methods of doing this, but keep hitting the same problem. Assuming I'm just thinking about this the wrong way.

This is what I currently Have.

$('a[class*=edit]').hide(); 

$('tr[class*=data]').bind("mouseover", function(e) {
  $(e.target).closest('a[class*=edit]').addClass("selected");
  $('a[class*=selected]:first').show();
}).mouseout(function() {
  $('a[class*=selected]').hide();
  $('a[class*=edit]').removeClass("selected");
})

Problem with the existing code is it's not adding the selected class unless you hover directly over the edit link. Like I mentioned above I need it to add the selected class when you mouse over anywhere in the that row. I also only want it to display the edit link for that specific row.

Any help would be really appreciated been pulling my hair out for a couple hours and I know it is probably something stupid. Thanks!

A: 

Try something like this, assuming that I have your logic right.

$(document).ready(function() {
  $('a.edit').hide(); 
  $('tr.data').hover(function() {  
    $(this).addClass("selected").find('a.edit').show();
  }, function() {  
    $(this).removeClass("selected").find('a.edit').hide();
 });
}):

Your particular error is most likely related to the fact that you are using the closest method which traveses UP the tree.

Update: Another possible reason for your code not working is because you aren't using the jquery document.ready feature. I've update my code with that.

bendewey
Thanks but, this code doesn't even add the selected class when you can hover directly over the edit link. Not sure closest is even close to the best method for this. I have tried 3 or 4 different ways of doing this tonight and each of them have there own set of issues. This was just the last attempt I had made.
gregf
In this most recent example I am adding the selected class to the tr when you hover, then finding the link and showing it. When your done hovering (ie mouseout), I'm removing the selected class from the tr, finding the edit link, and hiding it. Is this the right logic?
bendewey
I think his intention was to add the selected class to the link itself, which seems roundabout since only one should be showing at a time he could just style them always with the selected styles.
Paolo Bergantino
@Paolo you could be right, that is how I originally had it, but I would think from an asthetics point you would want to style the row as selected, so I'm going to leave my answer as is.
bendewey
Reason I was adding select was mostly for easy debugging in firebug. Figured once I got that behaving how I wanted I could clean it up. Thanks for everyone's explanations.
gregf
+7  A: 

A few things:

  • The string that you pass to the magical $() jQuery function can be the equivalent of what you may put in a CSS stylesheet if you wanted to style a particular element. The way you are using the selectors right now is wildly inefficient in addition to not being very clear. For example, using the =* selector is trying to find all links with the string edit anywhere in the class attribute. So links with a class of abceditabc would match. This makes jQuery do much more work than necessary trying to find these non-existent links. The accepted usage is instead to use a selector string such as a.edit which jQuery can quickly determine what it is and how to get it.
  • Whenever you do an event binding like you are doing, this refers to the element that the event is currently being acted on inside the function. Unless you are doing event delegation, you're not really going to use e.target.
  • The reason your code is only working when the hover is directly over the link is because whenever you hover over a different cell e.target would be a sibling td. closest does not have the ability to then traverse up that td, to the tr, to the next td down to the link. And even if it did, you probably want to avoid this as it's not necessary. This ties to the second point, as it is much easier to simply look for the link coming down from the table row.

So, keeping these things in mind, you can rewrite what you have to this:

$(function() {
    $('a.edit').hide(); // hide all links with a class of edit
    // act upon all table rows with a class of data
    $('tr.data').hover(function() {
        // at this point, 'this' is the table row that is being hovered
        // we can use the find function to locate the link with a class of edit
        // then add a class to it and show it.
        $(this).find('a.edit').addClass("selected").show();
    }, function() {
        // the second argument of the hover function is what should happen
        // when the mouse hovers out of the table row. In this case, we want
        // to find the link again, remove the class, and hide it.
        $(this).find('a.edit').removeClass("selected").hide();
    });
});

You can see the code this code acting on the HTML you posted here. Works for me on FF, IE.

A couple further suggestions:

  • Always have the jQuery documentation open. It is very good at explaining how things work.
  • Get used to using Firefox/Firebug when debugging your jQuery. Using console.log(this); inside your selectors when you want to see exactly what is being selected is a functionality that cannot be understated.
Paolo Bergantino
That's as perfect and simple as it gets. You and bendewey are like freaks when it comes to pouncing onto questions. What's your secret? PS... go Gators (and Golden Knights too.., but yeah...). ;)
KyleFarris
Uh oh. Don't make me flag your comment as offensive. ;) My secret is having way too much time in my hands.
Paolo Bergantino
This works exactly how I wanted. Thanks for explaining where I went wrong. I was just trying find again but like you said my whole issue was trying to select to much. Thanks.
gregf
I only kid man. I was just in Tally doing video for someone's wedding and they had their rehearsal video in some, like, club in the stadium. It was pretty nice. Bride was hardcore Gator, groom was hardcore Nole. They avoid the conversation at all costs.
KyleFarris
+1 good guess man
bendewey