jQuery – A Traversal Quickie

Paraphrased from the jQuery mailing list:

I have a table with links inside of it. Each <tr> has a unique ID assigned to it. How can I get the ID of the <tr> that contains the link that was clicked?

The following code snippet was included:

<tr id="1">
	<td>Name</td>
	<td>E-Mail</td>
	<td><a href="#" class="accept">Accept</a></td>
</tr>

jQuery provides a number of DOM traversal methods. While the initial thought might be to go with parent(), that would get the <td> containing the link. You could double up on parent(), but that seems a bit kludgy (IMO).

find() sounds like a good candidate, but unfortunately find() traverses down the DOM, not up.

In this case, the new-to-jQuery-1.3 method closest() will do the trick. As per the docs:

Get a set of elements containing the closest parent element that matches the specified selector, the starting element included.

Closest works by first looking at the current element to see if it matches the specified expression, if so it just returns the element itself. If it doesn’t match then it will continue to traverse up the document, parent by parent, until an element is found that matches the specified expression. If no matching element is found then none will be returned.

The key there is that closest() traverses up the document, parent by parent.

$( 'a.accept' ).click( function() {
	alert( $( this ).closest( 'tr' ).attr( 'id' ) );
});

For any “a” element of class “accept”, the code above will fire on the click event. $(this) refers to the element that triggered the click. Find the closest <tr> element, and get its ID attribute.

Putting it all together for your copying and pasting pleasure:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                    "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
	<title></title>

	<script src="http://code.jquery.com/jquery-latest.js"></script>
	<script>
		$( document ).ready( function() {
			$( 'a.accept' ).click( function() {
				alert( $( this ).closest( 'tr' ).attr( 'id' ) );
			});
		});
	</script>

<body>

<table>
<tr id="1">
	<td>Name</td>
	<td>E-Mail</td>
	<td><a href="#" class="accept">Accept</a></td>
</tr>
<tr id="2">
	<td>Name</td>
	<td>E-Mail</td>
	<td><a href="#" class="accept">Accept</a></td>
</tr>
</table>

</body>
</html>