Nelson Rothermel
Nelson Rothermel

Reputation: 9736

jQuery select table cells with specific header

I have a table with a "header" that user regular tr tags (not th). I need to find header "Col2" and then to each cell under Col2 add an anchor. I can do $("td:contains('Col2')) to find the header, but the data rows could also have "Col2". How would I search just the first row and then loop through the row cells?

<table>
  <tr>
    <td>Col1</td>
    <td>Col2</td>
  </tr>
  <tr>
    <td>Data1</td>
    <td>Data2</td>
  </tr>
  <tr>
    <td>Data3</td>
    <td>Data4</td>
  </tr>
</table>

Becomes:

<table>
  <tr>
    <td>Col1</td>
    <td>Col2</td>
  </tr>
  <tr>
    <td>Data1</td>
    <td><a href="?Data2">Data2</a></td>
  </tr>
  <tr>
    <td>Data3</td>
    <td><a href="?Data4">Data4</a></td>
  </tr>
</table>

Edit: I actually have more than one table in the same page. :first only matches the first row in the first table.

Update: Here is how I finally got it working. Thanks to everyone for your help! With a little from each of you and a little from the API docs it works. Now that I'm starting to get the hang of it, I can't imagine the pain of doing this without jQuery.

$('table').each(function(i, table) {
    $(table).find('tr:first > td:contains("Col2")').each(function() {
        var cellIndex = $(this).index() + 1;

        $(table).find('tr:not(:first) > td:nth-child(' + cellIndex + ')').wrapInner(function() {
            return $('<a />', { 'href': '?data=' + $(this).text() });
        });
    });
});

Upvotes: 2

Views: 9282

Answers (4)

Nick Craver
Nick Craver

Reputation: 630389

You can do it using .index() and .wrapInner(function) like this:

var i = $("table tr td:contains('Col2')").index() + 1;
$("table tr:gt(0) td:nth-child(" + i +")")​​​​​​​​​​​​​​​​​​​​​​​​​​​​​.wrapInner(function() {
    return $("<a />", { "href": "?" + $(this).text() });
});​

You can see an example here, this gets the index of the <td> that contains "Col2" (0-based) then uses the :nth-child() selector (1-based, so we add 1) to get the <td> elements you want to .wrapInner(). After that we're just returning the structure to wrap them in, generated via $(html, props).

Upvotes: 3

gblazex
gblazex

Reputation: 50109

[See it in action]

var index = $("table:first-child td:contains('Col2')").index() + 1;
$("tr:not(:first) :nth-child("+index+")").each(function(){
   var old = $(this).html();
   $(this).html("<a href='?"+old+"'>"+old+"</a>");                                          
});

Upvotes: 2

programatique
programatique

Reputation: 860

have you tried using the ":first" selector (including "not(:first)")

http://api.jquery.com/first-selector/

Upvotes: 1

spinon
spinon

Reputation: 10847

I would do the following:

search header row for column with matching criteria and then get column index. Then select all rows in the table starting from the second one that are found at that column index. Then create your anchors. I can try to write up some code if you need help with that.

Upvotes: 0

Related Questions