5

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.

Community
  • 1
  • 1
Yumecosmos
  • 884
  • 8
  • 22
  • I think what I'm gathering from this is that I need to have an id on the outer table. Thanks guys! Wish I could accept more than one answer. – Yumecosmos Aug 09 '12 at 15:58
  • Oops. This is almost an exact duplicate of http://stackoverflow.com/questions/6031638/get-most-upper-descendant-descendants-in-jquery Figures, I search for a week and then find the same question 3 hours after posting mine. >_ – Yumecosmos Aug 09 '12 at 18:29

2 Answers2

3

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.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • I'm a little confused as to how that would solve my issue... the nested ``s are still direct children of ``s so wouldn't that select them as well? (Sorry, I'm still a bit fuzzy on CSS3 selectors.) – Yumecosmos Aug 09 '12 at 15:22
  • Sorry, you need to start with the table. – Aaron Digulla Aug 09 '12 at 15:24
1

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

wirey00
  • 33,517
  • 7
  • 54
  • 65