How Do I Make a Full Table Row Clickable Using jQuery?

Back in 2004, I wrote an article about making a full table row clickable using JavaScript, so you could click anywhere in the table row to browse to a new page. That solution used quite a bit of in-line JavaScript to accomplish that task which adds to the size and complexity of the page. Since then, the JavaScript landscape has changed quite a bit with the introduction of JavaScript libraries such as Prototype and jQuery. Because my initial article is in the top 10 results for "full row select javascript" on Google, I figured it made sense to write a new, cleaner and more modern version of it using one of those libraries: jQuery.

Full Clickable Table Rows the jQuery Way

What I really like about jQuery is its unobtrusive nature. Using jQuery, it's very easy to completely separate your markup from the JavaScript code, something that's a lot harder to accomplish without it. This enables you to have clean markup and define your logic elsewhere in a script block or separate script file. This in turn makes it easy to create a page that looks good in modern browsers as well as in those that don't support JavaScript or don't have it turned on.

I'll show you the full code first, and then discuss some of its important parts afterward. You can try out a demo of the page here.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
  <title>Full Row Select Using jQuery</title>
  <script src="Scripts/jquery-1.4.2.min.js" type="text/javascript"></script>
  <style type="text/css">
    .Highlight
    {
      background-color: #dcfac9;
      cursor: pointer;
    }
  </style>
</head>
<body>
  <table width="100%" border="1" cellpadding="0" cellspacing="0" id="link-table">
  <tr>
    <td><a href="http://www.yahoo.com/">http://www.yahoo.com/</a></td>
    <td>1</td>
    <td>2</td>
    <td>3</td>
  </tr>
  <tr>
    <td><a href="http://www.microsoft.com/">http://www.microsoft.com/</a></td>
    <td>4</td>
    <td>5</td>
    <td>6</td>
  </tr>
  <tr>
    <td><a href="http://imar.spaanjaars.com/">http://imar.spaanjaars.com/</a></td>
    <td>7</td>
    <td>8</td>
    <td>9</td>
  </tr>
  </table>
  <script type="text/javascript">
    $(function ()
    {
      // Hide the first cell for JavaScript enabled browsers.
      $('#link-table td:first-child').hide();

      // Apply a class on mouse over and remove it on mouse out.
      $('#link-table tr').hover(function ()
      {
        $(this).toggleClass('Highlight');
      });
  
      // Assign a click handler that grabs the URL 
      // from the first cell and redirects the user.
      $('#link-table tr').click(function ()
      {
        location.href = $(this).find('td a').attr('href');
      });
    });
  </script>
</body>
</html>    

I am using pretty much the same HTML as in my initial article, with a few exceptions. First, notice the inclusion of the id attribute on the <table> element. This makes it easier to address the table from jQuery code. Secondly, I removed the onmouseover, onmouseout and onclick attributes from the table row. As you'll see in a bit, this is now all handled by jQuery. Finally, I added a new table cell containing an <a> element with the URL I want to link the row to. The jQuery code will hide that cell giving you the same table as in the initial article, shown in Figure 1 that displays the page while the mouse is over the first row:


Figure 1 (click to enlarge)

However, browsers that don't support JavaScript now see the table shown in Figure 2:


Figure 2 (click to enlarge)

As you can see, the links are now visible and clickable, resulting in a nice fall back scenario for browsers that don't handle JavaScript.

The next interesting piece of code to look at is the JavaScript block at the end. This code sets up jQuery's document ready function using $(function () { ... }); which fires when the browser is done loading the document. The first line of that code hides the first cell of each table row; effectively hiding the link that each cell contains:

$('#link-table td:first-child').hide();

This code first gets a reference to the table (using #link-table) and then to each "first child" of each table row (using td:first-child). It then hides these table cells using hide(). For more information about first-child, check out the jQuery documentation. Once this code is finished executing, the table looks the same as in the initial article.

The next piece of code assigns a handler to the hover function which fires when you move your mouse over the selected element. You can set up hover with two functions (which trigger on mouse over and on mouse out respectively), or with just a single one as I have done in this example. This causes the same piece of code to be called when you mouse over and mouse out again. Since I am using toggleClass (which adds a CSS class to the selected elements when it's not present and removes it when it is), this is very convenient:

$('#link-table tr').hover(function ()
{
  $(this).toggleClass('Highlight');
});      

In both cases, toggleClass('Highlight') is called, adding and removing the CSS class Highlight (defined at the top of the document) as you hover over the rows. Besides changing the background color of the table row, this class also changes the cursor into a hand icon, making it more obvious you can click the row. You can see how this behaves in the live demo.

The final piece of code (and the most important one) is the part that assigns a click handler to each row, taking the user to the URL defined in the <a> element in the first (and now hidden) table cell:

$('#link-table tr').click(function ()
{
  location.href = $(this).find('td a').attr('href');
});      

The this reference in this piece of code refers to the selected table row. By wrapping it in $() you end up with another jQuery matched set which in turn exposes a handy find method that lets you search for specific elements: all <a> elements in my case. The attr method then in turn returns the href property of the first element in the matched set. Since there's only one <a> element in each table row, that's exactly what I want. The returned href is then assigned to location.href, which causes the browser to request that page.

The final page is now a lot cleaner than the one from my initial article as it no longer contains in-line JavaScript in the markup. Additionally, it's now a lot easier to move the JavaScript code to a separate file, enabling reuse and a potential performance improvement. Finally, the code now gracefully degrades for browsers that don't support JavaScript by providing similar functionality. Although for those users the page doesn't look as good as the jQuery enabled one, they can still navigate to the URLs defined in the links.


Where to Next?

Wonder where to go next? You can post a comment on this article.

Doc ID 549
Full URL https://imar.spaanjaars.com/549/how-do-i-make-a-full-table-row-clickable-using-jquery
Short cut https://imar.spaanjaars.com/549/
Written by Imar Spaanjaars
Date Posted 07/28/2010 10:04

Comments

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the Doc ID of the document.

(Plain text only; no HTML or code that looks like HTML or XML. In other words, don't use < and >. Also no links allowed.