Solution: Make an entire table row clickable
April 27th, 2014To enable an entire row clickable with a specific link in a table has been a recurring problem for web developers. There are some solutions on the web, but they all seem to be lacking in some way or another. Here is my solution to link an entire row in a table, including working context menu and control click to open in new tab.
My requirements for the solution were:
1. The entire row should be linked without having to link each and every cell.
2. The html of the table should not be permanently altered by the script.
3. The right click context menu should work as if it was a normal link.
4. Control + click should result in the link being opened in a new tab/window, same as a normal link.
5. The target link should be possible to specify with a data attribute on the row, or by setting one of cells in the row.
6. The javascript should be unobtrusive and work with most browsers.
Note that the solution is dependent on jQuery.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | clickableRowListener = function(that, e) { var c = $(that).html(), url = $(that).parent().data("href") || $(that).parent().find("a").attr("href"); if (url && c.indexOf("<a") == -1 && c.indexOf("<button") == -1 && c.indexOf("<input") == -1) { $(that).html("<a href='" + url + "' target='" + (that.closest("table").hasClass("forceblank") || e.ctrlKey || e.which === 2 ? "_blank" : "") + "'>" + c + "</a>"); var a = $(that).find("a"); if (e.which === 3) { setTimeout(function () { a.parent().html(c); }, 300); } else { a[0].click(); a.parent().html(c); } } } // Onload: Add eventlistener $('table.clickable tr td').on('mousedown', function (e) { clickableRowListener(this, e); }); |
Add proper CSS to complete the solution. Here’s an example, these are not required but highly recommended to make the appearance complete.
1 2 3 | table.clickable tr:hover { background-color: Gray; } table.clickable tr > td { cursor: pointer; } table.clickable tr > td > a { display: block; text-decoration: none; } |
Usage: Add class “clickable” to the table. Optionally, add class “forceblank” to the table to force target new window for all links.
Link the row by either adding data-href attribute to the TR tag or link the first TD content.
1 2 3 4 | <table class="clickable"> <tr data-href="http://google.se"><td>This row will</td><td>link to google</td></tr> <tr><td><a href="http://google.se">This row will also</a></td><td>link to google</td></tr> </table> |
Demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Clickable table row demo</title> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" type="text/javascript"></script> <style> table.clickable tr:hover { background-color: Gray; } table.clickable tr > td { cursor: pointer; } table.clickable tr > td > a { display: block; text-decoration: none; } </style> <script> jQuery(function () { $('table.clickable tr td').on('mousedown', function (e) { clickableRowListener(this, e); }); }); function clickableRowListener(that, e) { var c = $(that).html(), url = $(that).parent().data("href") || $(that).parent().find("a").attr("href"); if (url && c.indexOf("<a") == -1 && c.indexOf("<button") == -1 && c.indexOf("<input") == -1) { $(that).html("<a href='" + url + "' target='" + (e.ctrlKey || e.which === 2 ? "_blank" : "") + "'>" + c + "</a>"); var a = $(that).find("a"); if (e.which === 3) { setTimeout(function () { a.parent().html(c); }, 300); } else { a[0].click(); a.parent().html(c); } } } </script> </head> <body> <br><br> <table class="clickable"> <tr data-href="http://google.se"><td>This row is</td><td>linked to google by data attribute</td><td><a href="http://www.bing.com" target="_blank">This linked cell should not be affected</a></td><td>Nor should <button onclick="alert('you clicked the button')">This button</button> I'd say</td></tr> <tr><td>This row is not</td><td>linked</td><td>at all</td><td>in any way</td></tr> <tr><td><a href="http://www.kulsomfan.se/2013/07/skratt-smittar/">Only first cell</a></td><td>has an url linked</td><td>but entire row is</td><td>clickable anyway</td></tr> </table> </body> </html> |