Animesh D
Animesh D

Reputation: 5002

jQuery: skipping first table row

This is the HTML:

<table id="tblTestAttributes">
    <thead>
        <tr> <th>Head 1</th> <th>Head 2</th> </tr>
    </thead>
    <tbody>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
    </tbody>            
</table>

This is the javascript to get the values of each row:

var frequencies = [];
if ($('#tblTestAttributes').length) {
    $('#tblTestAttributes tr').each(function () {
        var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
        alert(t);
        frequencies.push(t);
    });
}

I want to avoid the first row, which contains th elements which are just display headers and don't contain any data.

So I changed the selector to this:

#tblTestAttributes tr:not(:first-child)

This is skipping the second tr as well. What is happening here?

Upvotes: 3

Views: 6571

Answers (5)

frenchie
frenchie

Reputation: 51927

In terms of performance, using .find() will be better than resolving the selector with Sizzle.

$('#tblTestAttributes').find('tbody').find('tr').each(function () { ... });

Here's the jsPerf to show it.

Upvotes: 3

Dipesh Parmar
Dipesh Parmar

Reputation: 27364

Simple you can use below code

$('#tblTestAttributes tr:not(:has(th))').each(function () {

Upvotes: 7

Dr.Molle
Dr.Molle

Reputation: 117324

use

#tblTestAttributes tr:gt(0)

or

#tblTestAttributes tbody tr

I would recommend the 2nd, because it may take advantage of querySelectorAll and should be the fastes solution.

your approach didn't work as expected, because the 2nd tr is also a first-child(of tbody)

Upvotes: 3

XCS
XCS

Reputation: 28137

Use tr + tr selector, which gets all tr that appear after another tr, so the first one is skipped.

Also no need to check if table exists, as in that case $.each wouldn't even get executed.

var frequencies = [];
    $('#tblTestAttributes tr + tr').each(function () {
        var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
        alert(t);
        frequencies.push(t);
    });

After your edit:

Simply select only all tr inside tbody:

$('#tblTestAttributes tbody tr').each(function(){
    ...
}

Upvotes: 2

Denys S&#233;guret
Denys S&#233;guret

Reputation: 382142

It happens because the second row is, in fact, the first child of the tbody just like the first row is the first child of the thead.

To only take the elements you need, I'd suggest something nearer from your need :

#tblTestAttributes tr:has(td)

Don't forget to get rid of those duplicate txtDesc id, this is illegal in HTML, use a class instead.

Upvotes: 1

Related Questions