Josh Earl
Josh Earl

Reputation: 18361

Finding parent row of form text input

I'm trying to use data- attributes in an HTML table to store data about an item that will later be used in an ajax call, but I'm having trouble with my jQuery selection when I try to get the data back out.

This works:

var listItemId = $(this).parent().parent().attr('data-id');

However, the .parent().parent() selector is too fragile--it'll break if I ever change my HTML structure.

This is what I'd like to do, but it is returning undefined:

var listItemId = $(this).parent('.list-item').attr('data-id');

My HTML looks like this:

<tr class="list-item" data-id="1">
   <td>
     <input value="Some text entered by the user" type="text" >
   </td>
</tr>

What am I missing?

Upvotes: 13

Views: 29467

Answers (4)

nafsin vattakandy
nafsin vattakandy

Reputation: 1

$(this).closest('tr').attr('data-id');

This will be the best solution for your problem. The code will not be depended on you html structure, unless you introduce new <tr> tag in between

Upvotes: 0

arb
arb

Reputation: 7863

I would suggest:

var listItemId = $(this).parents('tr').data('id');

The class selector is the slowest of all the jQuery selectors and should avoided unless there is no other way to go the information you need.

UPDATE

I fixed the syntax to make use of the .data() method correctly. This way only works in version 1.4.3 or higher.

Upvotes: 3

roselan
roselan

Reputation: 3775

internally, jquery uses .closest for this kind of stuff.

var listItemId = $(this).closest('tr').attr('data-id');

moreover if you have nested tables (which I never saw, but we never know), you have to select the first 'tr' too. (it's more useful with looking for divs than rows though). However, for code unification, I never use parents when I need closest. That way, the function names implies it's meaning exactly (closest parent), while .parents() leaves more room to interpretation, and thus reduce code readability (imo)

performance wise, they are equivalent (check this jsperf )

finally, you can consider a pure javasrcipt approache too: parentNode (by miles faster than anything else, if you really need speed)

in your case:

var listItemId = $(this.parentNode.parentNode).attr('data-id');

or

var listItemId = this.parentNode.parentNode.attributes['data-id'].value;

NB: pure javascript methods need valid html to work, unlike the one in your question (close your input tag, and add a table one).

here is a little fiddle

Upvotes: 27

Manuel van Rijn
Manuel van Rijn

Reputation: 10315

try

var listItemId = $(this).parents('.list-item').attr('data-id');

parents() goes up in the tree until it matches the selector

Upvotes: 4

Related Questions