5

I have a script which can make each table row clickable (as a link), however I need the last column to remain untouched as this column as an 'edit' button. Can anyone help me amend the script so it'll work?

Here the jQuery so far:

$(document).ready(function() {
  $('#movies tr').click(function() {
    var href = $(this).find("a").attr("href");
    if(href) {
      window.location = href;
    }
  });
});

Here's the HTML for one row:

<table id="movies">
  <tr class='odd'>
    <td>1</td>
    <td><a href='/film.php?id=1'></a>Tintin</td>
    <td>Tintin and Captain Haddock set off on a treasure hunt for a sunken ship.</td>
    <td><a href='/edit.php?id=1'>edit</a></td>
  </tr>
  .....
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Dan
  • 511
  • 2
  • 9
  • 19

6 Answers6

11

you need to go one step deeper and control the tr's elements, bind a click handler to each td which is not the last in the tr:

$(document).ready(function()
{
   $('#movies tr').each(function(i,e)
   {
      $(e).children('td:not(:last)').click(function()
      {
         //here we are working on a td element, that's why we need
         //to refer to its parent (tr) in order to find the <a> element
         var href = $(this).closest("tr").find("a").attr("href");
         if(href)
         {
            window.location = href;
         }              
      });
   });
});
Dalen
  • 8,856
  • 4
  • 47
  • 52
3

alternatively, you might use event.stopImmediatePropagation() in the last col button event handler.

$('#movies tr').click(function () {
    var href = $(this).find("a").attr("href");
    if(href) window.location = href;
});

$('#movies input:button').click(function (e) {
    // button's stuff
    e.stopImmediatePropagation();
});

the advantage (or inconvenient) is that is allow you to click around the button in the last cell. (in the margin padding). I can be an inconvenient, as button miss click would open the linked page and surprise the user.

Another alternative can be to use only one event handler, which decide action to do with event.which. It is my favorite method as it limits the number of event handlers. the use of delegate is for the same reason. One handler by table, instead of one by row.

$('#movies').delegate('tr', 'click', function (e) {
    if ( $(e.target).is('input:button') )  {
        // button's stuff
    }
    else {
        var href = $(this).find("a").attr("href");
        if(href) window.location = href;
    }
});
roselan
  • 3,755
  • 1
  • 20
  • 20
0
$('tr').each(function () {
    $(this).children('td:not(:first)').click(function () {
        window.location = $(this).closest('tr').data('href');
        return false;
    });
});
DesignerUXTX
  • 104
  • 1
  • 15
0

Let me post another example for selecting/unselecting rows in DataTables by clicking on any but a particular column.

$('#my_table_id tbody').on( 'click', 'td:not(.prohibited_td_class)', function() {
      $(this).closest("tr").toggleClass('selected');
      // If you are also using DataTables, see which rows you've selected.
      alert(""+table.rows('.selected').toJQuery()[0]);
});
Sergey Orshanskiy
  • 6,794
  • 1
  • 46
  • 50
0

Try this

$(document).ready(function() {
  $('#movies tr:not('.odd')').click(function() {
    var href = $(this).find("a").attr("href");
    if(href) {
      window.location = href;
    }
  });
});
Rupesh Pawar
  • 1,887
  • 12
  • 17
  • 2
    You are using the quotes wrong. It should be: `$('#movies tr:not(".odd")')` -- Aren't you skipping rows instead of columns here? – Smamatti Nov 05 '11 at 11:28
  • I am not skipping rows. I need it to apply to all rows, but should not apply to the last column – Dan Nov 05 '11 at 12:05
0

I'd suggest to instead have the <td>s paddinng to 0 with a certain class or simliar, and have the <a> tags inside be display: block so that the browser simply clicks on the <a>-tag on the entire <td>.

The advantage here is that your browser can handle the links much better and for instance open the link in a new window if desired.

It may not suit your solution here, but it's worth considering for similiar cases.

Robin Castlin
  • 10,956
  • 1
  • 28
  • 44