0

I am trying to select the highest level of tds in a nested table structure like this (inside the first level tds there are more tables with more tds that shouldn't be selected

<table>
  <tr>
    <td>        <!-- this is what I want to select -->
      <table /> <!-- more td's inside that I don't want to select -->
    </td>
  </tr>
  <tr>
    <td>        <!-- this is what I want to select -->
      <table /> <!-- more td's inside that I don't want to select -->
    </td>
  </tr>
</table>

To select the desired tds would be easy: table > tr > td. However there might be tables with tbody tags:

<table>
  <tbody>
    <tr>
      <td>        <!-- this is what I want to select -->
        <table /> <!-- more td's inside that I don't want to select -->
      </td>
    </tr>
    <tr>
      <td>        <!-- this is what I want to select -->
        <table /> <!-- more td's inside that I don't want to select -->
      </td>
    </tr>
  </tbody>
</table>

That itself would be easy as well: table > tbody > tr > td.

How can I find an easy expression that doesn't rely on the > child selector and works universally?

Something like table tr > td (which obviously wouldn't work since it selects tds inside the nested table. Thanks!

4
  • You'll have to find something unique about the wrapping table to target it, like it's parent element, an ID, the index etc. Commented Mar 28, 2014 at 15:27
  • table > tbody > tr > td will work universally and would also probably be the fastest solution. Why are you against it? Commented Mar 28, 2014 at 15:32
  • 1
    most browsers will assume you forgot to add tbody and will add it themselves (with some exceptions because of doctype). Also I know this sounds dull but if you only have two posibilities wouldn't a selector like $('table > tbody > tr > td', 'table > tr > td'); do the trick? Without that it will require alot of parent proofing to get the right td Commented Mar 28, 2014 at 15:36
  • @Spokey of course it would work but I am eager to learn - so I thought there might be a better way to do so... Commented Mar 28, 2014 at 15:40

2 Answers 2

1

As I expressed in my comment, I'm all in favor of table > tbody > tr > td, but as an alternative, you can use

td:not(td td)

This selects all td elements that are not descendants of a td element. But note that this will only work with jQuery, because you usually cannot use complex selectors with :not.

Alternatively, use the .not method:

$('td').not('td td')
Sign up to request clarification or add additional context in comments.

Comments

0

The correct answer is:

$('#tbl1').find('tr:first').parent().children().not(':not(td)')

.not(':not(td)') removes not td tags.

Examples:

<table id="tbl1">
<tr>
  <td>1</td>
  <input type="hidden" name="hidden1" value="something"> 
  <td>2</td>
  <td> 
       <table>
          <tr><td>1</td>
            <input type="hidden" name="hidden1" value="something"> 
            <td>2</td>
          </tr>
        </table>
</td>
</tr>
</table>

<table id="tbl2">
<tbody>
<tr>
  <td>1</td>
  <input type="hidden" name="hidden1" value="something"> 
  <td>2</td>
  <td> 
       <table>
          <tr>
            <td>1</td>
            <input type="hidden" name="hidden1" value="something"> 
            <td>2</td>
          </tr>
        </table>
</td>
</tr>
</tbody>
</table>

Code:

var r1 = $('#tbl1').find('tr:first').children();
var r2 = $('#tbl1').find('tr:first').children().not(':not(td)');
var r3 = $('#tbl2').find('tr:first').children();
var r4 = $('#tbl2').find('tr:first').children().not(':not(td)');

console.log ("r1: ", r1.length);
console.log ("r2: ", r2.length);
console.log ("r3: ", r3.length);
console.log ("r4: ", r4.length);

Output:

"r1: ", 4
"r2: ", 3
"r3: ", 4
"r4: ", 3

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.