Skip to content

Instantly share code, notes, and snippets.

@jamesarosen
Created April 1, 2011 19:26
Show Gist options
  • Save jamesarosen/898696 to your computer and use it in GitHub Desktop.
Save jamesarosen/898696 to your computer and use it in GitHub Desktop.

Let's say you have a <table> of Cats, each of which has a link to a "more info" page:

NameBornAdopted?
Claudius17 FebYes
Willow29 FebNo
Sawtooth Sparrow-Eater08 MarNo
<!-- source: -->
<table class='cats'>
  <thead>
    <tr><th>Name</th><th>Born</th><th>Adopted?</th></tr>
  </thead>
  <tbody>
    <tr><td><a href='#/cats/14-claudius'>Claudius</a></td><td><time datetime="2011-02-17">17 Feb</td><td>Yes</td></tr>
    <tr><td><a href='#/cats/15-willow'>Willow</a></td><td><time datetime="2011-02-29">29 Feb</td><td>No</td></tr>
    <tr><td><a href='#/cats/16-Sawtooth-Sparrow-Eater'>Sawtooth Sparrow-Eater</a></td><td><time datetime="2011-03-08">08 Mar</td><td>No</td></tr>
  </tbody>
</table>

Your product team says, "we'd really like it if the user could click anywhere on the row to go to the 'more info' page." Your first thought is to move the <a> tags outside the <tr>s:

NameBornAdopted?
Claudius17 FebYes
Willow29 FebNo
Sawtooth Sparrow-Eater08 MarNo
<!-- source: -->
<table class='cats'>
  <thead>
    <tr><th>Name</th><th>Born</th><th>Adopted?</th></tr>
  </thead>
  <tbody>
    <a href='#/cats/14-claudius'><tr><td>Claudius</td><td><time datetime="2011-02-17">17 Feb</td><td>Yes</td></tr></a>
    <a href='#/cats/15-willow'><tr><td>Willow</td><td><time datetime="2011-02-29">29 Feb</td><td>No</td></tr></a>
    <a href='#/cats/16-Sawtooth-Sparrow-Eater'><tr><td>Sawtooth Sparrow-Eater</td><td><time datetime="2011-03-08">08 Mar</td><td>No</td></tr></a>
  </tbody>
</table>

Sadly, that's not valid HTML. Even more sadly, browsers aren't too happy with this markup.

"I know," you say, "let's solve the problem with some spiffy Javascript." You return to the original markup and add some jQuery:

$('table.cats tr').each(function() {
  var href = $('td:first-child a', this).attr('href');
  $(this).click(function() { window.location.href = href; });
});

Ruxpin, Your UX-professional alter-ego also reminds you to make the whole <tr> feel like a link since it's clickable:

table.cats tr { pointer: cursor; }

This solves the problem, but it introduces a new one: users who command-click (or control-click on Windows) will get both the browser default behavior (opening the "more info" page in a new tab) and your custom behavior (opening the "more info" page in the current tab). This is... less than optimal.

One solution to the double-open problem is to prevent the default behavior on the <a>:

$('table.cats tr td:first-child a').click(function(event) {
  event.preventDefault();
  event.stopPropagation();
});

But this is a cut-off-the-PBR-to-spite-the-hipster problem since this now stops the user from ever using command-click on the link to open the "more info" page in a new tab.

I haven't been able to think of any semantically-correct solutions that work across browsers.

I tried the following:

$('table.cats tr').click(function(event) {
  $('td:first-child a', this).trigger(event);
});

but triggering a click event doesn't actually cause the browser to follow the link; it only triggers any registered click handlers.

The best I've come up with that actually works is

$('table.cats tbody tr').each(function() {
  var myInfoLink = $('td:first-child a', this)[0];
  if (!myInfoLink) { return; }
  $(this).click(function(event) {
    if (!event) { return; }
    // don't override link-click behavior:
    if (event.target === myInfoLink) { return; }
    event.preventDefault();
    event.stopPropagation();
    if (event.ctrlKey || event.metaKey) {
      window.open(myInfoLink.href, '_blank');
    } else {
      window.location.href = myInfoLink.href;
    }
  });
});

I'd love to hear any suggestions.

@jish
Copy link

jish commented Apr 3, 2011

Added another idea here: https://gist.github.com/900620

The downside is that you can not command click on other parts of the row, just the link.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment