jQuery conditional selector for table rows
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 td
s 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
}
});
fearofawhackplanet
Updated on July 16, 2022Comments
-
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"
orcolspan is not set
or whatever it would need to be? -
fearofawhackplanet almost 14 yearsthat's probably a good idea, I'll bear that in mind next time
-
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 almost 14 yearsI 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 almost 14 years@SLaks, you may want to add another closing parenthesis to that selector.
-
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 almost 14 years@J-P: Even with this corrections, the first solution is more then 10 times faster.
-
IsmailS almost 14 yearsI think people are voting because it seems it should work as per the jQuery docs.
-
jAndy almost 14 years@J-P: ok fixed all now, it's still ~300ms vs. ~2500ms in FireFox 3.6.6.
-
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 almost 14 years@J-P: wow, indeed. It throws an error.
:has(td+td)
is way better, but still almost 50% slower. -
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 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.