Yumecosmos
Yumecosmos

Reputation: 934

Select only first level of descendants with jQuery - is there a better way?

I'm trying to build a jQuery plugin to lock rows or columns in a table a la Excel's freeze panes. (There are a number of other fine solutions for this, but none of them have worked for me for various reasons. I think it might have something to do with the table being inside a modal popup. But I digress.)

As part of this I'm trying to select the first n rows or columns of a particular table, specified in the plugin options. The trouble is that some of the rows contain other nested tables. I unfortunately can't do anything about this. So my question is, how do I get only the first level of <tr>s within a table? Using .children('tr') isn't always working because the row isn't necessarily the direct child of the table--there might be a <thead> or (ideally) the user might be able to call the plugin on a containing element and it should be smart enough to find the table(s) inside it.
Edit: Actually, now I'm thinking that second bit is not going to work if we have to select the table by id. But I don't think it's too much to ask that people use the plugin only on a table, since that's kind of what it's for...

In short: how do I select only the first level of table rows that may or may not be the direct child of a particular containing element?

What I came up with so far, based on the second half of this answer, was this:

$el.find('tr:not(tr tr):lt('+base.options.rows+')')

and for the columns:

$el.find('tr:not(tr tr)').find('(td,th):lt('+base.options.columns+')')

But that seems horribly long and clunky and I'm wondering if there's a shorter/cleaner way of doing it. Or is there a way just using plain old javascript?

Edit 2: Apparently the selector version is actually faster than .not(). News to me.

Upvotes: 6

Views: 2519

Answers (2)

wirey00
wirey00

Reputation: 33661

Give your table an "ID" so you have a starting point and use the direct child selector

$('tableID, tableID > tbody,tableID > thead, tableID > tfoot').children('tr')

As tr can be under the table, tbody, or thead for that specific table

Upvotes: 1

Aaron Digulla
Aaron Digulla

Reputation: 328604

Use the correct selector. In this case, that would be >, the direct child selector:

$el.find('#table > tbody tr > td, #table > tbody tr > th');

See "jQuery Selectors" for other options.

Alternatively, just iterate over all direct children of tbody:

var cells = $el.children('tbody').children('tr').children();

Since only td and tr are allowed as children of tr, that should already be the list that you want.

Upvotes: 4

Related Questions