Reputation: 11134
I want select first row from any cell so I just wrote javascript like.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody tr:first");
alert($(firsttd).text());
And my table is below
<table id="idTable_1" border="1px" width="97%" class="tblDragTable" data-numberofrows="2" data-numberofcolumns="2">
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
</table>
when I use find()
it giving me correct result
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).parents("table tbody").find("tr:first");
But I just want to know why the above code return second tr
instead of first tr
HERE IS MY JSBIN http://jsbin.com/lisozuvade/1/watch?html,js,output
Upvotes: 0
Views: 173
Reputation: 123
If I'm not mistaken, the parent hierarchy of cellno_111
is:
trno_11
-> tbody
-> table
In your first example, the first tr
parent cellno_111
finds is trno_11
and not trno_10
. It does not have a trno_10
parent.
The reason it does work with find()
, is because you select the tbody
and then search for the first tr
child the tbody
has.
Upvotes: 1
Reputation: 93601
The reason why it fails is because calling parents
with a filter of table tbody tr
will only match the immediate parent TR
. The other TR falls outside of the ancestors so :first
will match the only TR
it finds.
If you try this you will see what is going on:
alert($(curcontrol).parents('table tbody tr')[0].outerHTML);
returns this:
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
then try this:
alert($(curcontrol).parents('table tbody')[0].outerHTML);
which returns this:
<tbody>
<tr id="trno_10">
<td class="tblCell" id="cellno_100">0</td>
<td class="tblCell" id="cellno_101">0</td>
</tr>
<tr id="trno_11" height="1">
<td class="tblCell" id="cellno_110" width="1">1</td>
<td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
</tr>
</tbody>
JSFiddle: http://jsfiddle.net/TrueBlueAussie/j28g27m1/
So your first example only looks at the ancestors (one TR
) and returns the first match. The second example looks further back up the tree, then finds all TR
s in the tbody
then chooses the first
one.
A preferred, slightly faster, way would be to use closest()
and find()
e.g.
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr:first");
or faster yet (as selectors are evaluated right-to-left):
var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr").first();
e.g. http://jsfiddle.net/TrueBlueAussie/j28g27m1/1/
Upvotes: 3
Reputation: 3407
You're asking for parents of #cellno_111
, only that tr
is.
Also keep in mind that :first
is like .first()
as it filters to the first element in the set of matched elements, it has nothing to do with being the first child of something. If you want multiple elements, which are first children you should use :first-child
.
.parents(table tbody tr:first)
: query the parents of the element for a tr
which is inside of table
and tbody
, then pick the first
.parents("table tbody").find("tr:first")
: query the parents of the elements for a tbody
which is inside a table
, then find all tr
s inside of it, then pick the first of them
PS: I suggest using closest
instead of parents
as the go-to DOM navigation method for ancestors; most of the times it's way more practical and easier to understand.
Upvotes: 3
Reputation: 6947
Actually, you need to understand what each selector is doing. Try with several console.log, you'll see:
$(curcontrol).parents();
This return a set of elements. In this set, there is only 1 tr
, the parent of your curcontrol
td tag.
You can indeed filter this specific set by adding a extra filter :
$(curcontrol).parents("table tbody tr:first");
But as I just explained, the original set only contains a single TR, so the first one returned is actually the only one returned.
Your find()
approach is different, you specify a specific (parent) element and with the find()
you search trough children, which explains in this case the correct behaviour.
Upvotes: 1