jQuery conditional selector for table rows

12,622

Solution 1

Don't refine your selector, it won't scale well because jQuery will have to evaluate every child element. Avoid the error instead...

$('.productList tbody tr').each(function() { 
   var orderCode = $(this).find('td:eq(1)');

   if(orderCode.length > 0) { // Make sure it exists
     orderCode = orderCode.html().trim(); 
     // do stuff 
   }
}); 

Solution 2

Like this:

$('.productList tbody tr:has(td:nth-child(2))').each(function() {
    ...
});

This will only select <tr> elements that have a <td> that is the second child of its parent. (the nth-child selector is one-based)

Solution 3

If you can change how you generate the table, using classes is a cleaner solution:

<td class="item-name"> item </td>
<td class="order-code"> order code </td>
<td class="item-price"> price </td>

Then select only the desired class:

var orderCode = $(this).find('td.order-code').html().trim();
if(orderCode)
{
  //do stuff
}

This will also give you increased flexibility in styling the table with CSS, and your code won't break if you add or reorder columns.

Solution 4

You could test how many tds there are:

$.each($('.productList tbody tr'), function() {
    var tds = $(this).find('td');
    if(tds.length >= 2) {
        var orderCode = tds.eq(1).html().trim();
        // do stuff
    }
});
Share:
12,622
fearofawhackplanet
Author by

fearofawhackplanet

Updated on July 16, 2022

Comments

  • fearofawhackplanet
    fearofawhackplanet almost 2 years

    I have a table with data in:

    <td> item </td><td> order code </td><td> price </td>

    I'm processing the table with jQuery which needs to find the order code:

    $.each($('.productList tbody tr'), function() {
        var orderCode = $(this).find('td:eq(1)').html().trim();
        // do stuff
    });
    

    If there are no products, the table shows a message:

    <td colspan="3"> There are no products to display </td>

    The above row causes the jQuery function to bomb out. What's the most robust way to use a conditional selector to ignore the "no products" row? Is there a selector for colspan="1" or colspan is not set or whatever it would need to be?

  • fearofawhackplanet
    fearofawhackplanet almost 14 years
    that's probably a good idea, I'll bear that in mind next time
  • James
    James almost 14 years
    @jAndy, that test is simply abysmal. You're testing your solution 500 times, yet SLaks' is tested 10000 times! And you're not re-defining the start variable to +new Date after your solution runs...
  • IsmailS
    IsmailS almost 14 years
    I don't know why it is not selecting anything( .length shows 0). @SLaks, I think you have missed that closing parenthesis. This works. stackoverflow.com/questions/3281384/…
  • James
    James almost 14 years
    @SLaks, you may want to add another closing parenthesis to that selector.
  • jAndy
    jAndy almost 14 years
    @J-P: you're right, my bad. 10000 hung Firefox I had to redfine it. Still, it's slowish. new link: jsfiddle.net/cfznm/2
  • Felix Kling
    Felix Kling almost 14 years
    @J-P: Even with this corrections, the first solution is more then 10 times faster.
  • IsmailS
    IsmailS almost 14 years
    I think people are voting because it seems it should work as per the jQuery docs.
  • jAndy
    jAndy almost 14 years
    @J-P: ok fixed all now, it's still ~300ms vs. ~2500ms in FireFox 3.6.6.
  • James
    James almost 14 years
    @jAndy, your test is also missing the closing parenthesis from Slaks' selector. For some reason, his selector (even with the correct parenthesis) throws an error. :has(td+td) might be better...
  • jAndy
    jAndy almost 14 years
    @J-P: wow, indeed. It throws an error. :has(td+td) is way better, but still almost 50% slower.
  • James
    James almost 14 years
    @jAndy, true. Btw, yours can be made faster with $('table tbody tr') instead of $('table').find('tbody').find('tr') (faster in chrome, by about 40ms).
  • jAndy
    jAndy almost 14 years
    @J-P: true, $('table').find('tr') will perform almost the same. Selecting mostly by css querystrings may only be faster on browser that support a native query selector engine.