13

What is the best way to make a row of an HTML table a link? I currently am using jquery to zebra stripe the rows and also to highlight the onmouseover/off selected row, so if JavaScript is the answer, please use jquery.

Termininja
  • 6,620
  • 12
  • 48
  • 49
hacintosh
  • 3,784
  • 4
  • 19
  • 22
  • The google search query 'jquery tr link' gave me a few solutions already. Maybe you should try it too? I'm not answering your question because I have no jquery experience at all so I might be saying something 'stupid' ;-) – RuudKok Feb 20 '09 at 12:25
  • 8
    yes it gives you results but I wouldn't consider most of them answers. If I google "dog poop tr link" I get "answers" also. :) – hacintosh Feb 20 '09 at 12:41
  • 1
    The two proposed JQuery solutions are problematic for usability and accessibility. The CSS solution is better for any public website. See my comments there. – Andy Baker Mar 25 '09 at 17:50

6 Answers6

40

I just use css:

<style>
table.collection {width:500px;border-collapse:collapse;}
table.collection tr {background-color:#fff; border-bottom: 1px #99b solid;}
table.collection tr:hover {background-color:#ffe;}
table.collection td {display:table-cell;border-bottom: 1px #99b solid; padding:0px;}
table.collection td a {text-decoration:none; display:block; padding:0px; height:100%;}
</style>
<table class="collection">
<tr>
    <td><a href="#">Linky1</a></td>
    <td><a href="#">Data1</a></td>
</tr>
<tr>
    <td><a href="#">Linky2</a></td>
    <td><a href="#">Data2</a></td>
</tr>
</table>
Nick Van Brunt
  • 15,244
  • 11
  • 66
  • 92
  • 4
    Best solution by far. Browser still see's this as a link so 'open in tab' or 'copy link' will work. The other solutions break my browser! There is scope for a JQuery solution that automates the above by DOM manipulation. – Andy Baker Mar 25 '09 at 17:48
  • 2
    I'm having trouble with this solution. If one of the table cells contains enough content to wrap lines, the height of neighbouring cells won't stretch to the full height. Have you found a workaround for this case? – troelskn May 28 '09 at 09:32
  • This sounds like an IE quirks mode issue. I don't see this in firefox or IE 7-8 with "-//W3C//DTD XHTML 1.0 Strict//EN". It also may not work in IE 6 (but what does?) – Nick Van Brunt Jun 11 '09 at 19:51
  • on second thought - adding height:100%; to the a style would most likely fix it (see the last edit). – Nick Van Brunt Jun 11 '09 at 19:55
  • 1
    height:100% doesn't fix it for me in FF 3.6, HTML5 doctype. – Simon D Feb 17 '10 at 18:03
  • 2
    The problem with this approach is that you have lots of links, so if someone is navigating content via the tab key / a screen reader / etc they'll have to skip past a lot of links to get to the next one. – Quentin Mar 02 '12 at 17:30
  • 2
    Bravo for making the clickable stuff an actual link. Even better, make the href something that will work when javascript is disabled. If tabbing is a concern, set all but one anchor on a row to tabIndex=-1 – Dave Mar 09 '12 at 15:34
  • for this solution to work in xhtml/1999 , an absolute height is required – dube Mar 20 '12 at 09:21
18
$(document).ready(function(){
   $("tr").click(function(){
      /* personally I would throw a url attribute (<tr url="http://www.hunterconcepts.com">) on the tr and pull it off on click */
      window.location = $(this).attr("url");

   });
});
hunter
  • 62,308
  • 19
  • 113
  • 113
2

You do not need jQuery if you don't mind replacing the table by generic elements:

<style>
    .table {
        border-collapse: collapse;
        border-spacing: 0;
        display: table;
    }
    .tr {
        display: table-row;
    }
    .td {
        display: table-cell;
    }

</style>

<section class="table">
    <a class="tr" href="#">
        <div class="td">
            A
        </div>
        <div class="td">
            B
        </div>
        <div class="td">
            C
        </div>
    </a>
</section>
  • 1
    You do not keep the semantic meaning you get by using table, tr and td tags with this solution. – Andreas Nov 01 '13 at 07:42
2

Register a onclick event handler for the tr element. Something like this using jQuery:

$("tr").bind("click", function(){ 
  window.location = 'http://www.example.com/'; 
});
Ronny Vindenes
  • 2,361
  • 1
  • 18
  • 15
1
<td>
    <a href="/whatevs/whatevs">
        <div class="tdStreacher"> linkName
        </div>
    </a>
</td>

.tdStreacher{
    height: 100%;
    width: 100%;
    padding: 3px;
}

This way, all the area of each cell will act as a link, hence, the whole row act as a link.

uggeh
  • 11
  • 1
  • 1
    didn't see the accepted solution huh? Does not work in 1999/xhtml because height:100% does not necessarily span the complete cell. – dube Mar 20 '12 at 09:22
1

Here is a jQuery plugin based on Nick's solution.

(function($) {
  $.fn.linkWholeRows = function() {

    // for each object
    return this.each(function() {

      // for each row
      $(this).find('tbody tr').each(function() {
        // get the first link's href
        var href = $(this).find('td > a').attr('href');
        // if none found then
        if (href === undefined) {
          return true; // continue
        }

        // wrap all cells with links that do not already have a link
        $(this).children().not(':has(a)').each(function() {
          $(this).contents().wrapAll('<a href="' + href + '" />');
        });

        // apply the row's height to all links
        // in case that the cells' content have different heights
        var height = $(this).children().css('height');
        $(this).find('td > a').each(function() {
          $(this).css('height', height);
          // do not forget to apply display:block to the links
          // via css to make it work properly
        });
      }); // each row

    }); // each object

  };
})(jQuery);

Expects rows to be wrapped in tbody's. The height is set explicitly as Nick's original solution did not work for me on neighbouring cells with different heights. Make sure to style a-elements as blocks. If you want to apply padding, apply it to the a-elements instead of table cells:

a {
  display: block;
  padding: 0.25em 0.5em;
}
tbody td { padding: 0; }

Simply call

$('#your-table').linkWholeRows();

Hope it helps. Cheers, Richard

Richard Kiefer
  • 1,814
  • 2
  • 23
  • 42