tags:

views:

102

answers:

5

Suppose I have a table like so:

<table>
    <tr><td class="this-is-a-label">Label Cell</td></tr>
    <tr><td>Detail 1</td></tr>
    <tr><td class="selected">Detail 2</td></tr>
</table>

I want to be able to grab the previous "Label Cell" from the "Selected" cell.

My jQuery script should be something like:

$('.selected').each(function() {
    var label = $(this).parent().prev('tr td.this-is-a-label');
    //... do what I need with the label ...
});

But it's not working.

Does anyone have any suggestions?

+3  A: 

You can do this:

$('.selected').each(function() {
  var label = $(this).closest('tr').prevAll('tr:has(td.this-is-a-label):first')
                     .children('td.this-is-a-label');
  //... do what I need with the label ...
});

This isn't ideal though, it's a rather expensive DOM traversal, if you can guarantee it's always 2 rows behind, you can do this:

$(this).closest('tr').prev().prev().children('td.this-is-a-label')

...which is much faster, it just depends what assumptions and guarantees you can make about your markup, if there are any certainties, you can definitely make it faster.

Nick Craver
Yes it's rather expensive, but it's necessary. Unfortunately there aren't any guarantees.Thank you for your help.
Huy Tran
+3  A: 

How about:

var label = 
  $('.selected').parent().prevAll('tr').children('td.this-is-a-label')[0];
Chris Lercher
A: 

Here's how you get references to both the <tr> and <td> dom elements:

$("tr:has(td.selected)").each(function(i, trSel){
    var trLabel = $(trSel).prevAll("tr:has(td.this-is-a-label)").get(0);

    var tdSel = $(trSel).children("td.selected").get(0);
    var tdLabel = $(trLabel).children("td.this-is-a-label").get(0);

    console.log(trSel, tdSel);
    console.log(trLabel, tdLabel);
});
Peter McGrattan
A: 

I created a little plugin in response to this post for the purpose of finding a cell which is relative to the current cell:

$.fn.cellFromCell = function(r,c,upOrDown) {
    if(upOrDown == 'down') {
        return $(this).parent().prevAll(':eq(' + r + ')').find('td:eq(' + c + ')').text();
    } else {
        return $(this).parent().nextAll(':eq(' + r + ')').find('td:eq(' + c + ')').text();
    }
}

alert($('.selected').cellFromCell(1, 0, 'down')); // alerts "Label Cell"
alert($('.this-is-a-label').cellFromCell(0, 0)); // alerts "Detail 1"
​

I used your html for a simple test case. You can mess with it here: http://jsfiddle.net/6kfVL/3/

karim79
+1  A: 
$("td.selected").parents("table").find("td.this-is-a-label").text();
Aneesh