Reputation: 10077
In this script I'm writing, I find myself using .parent() up to seven times in a row to get elements. While this works, it seems like there could/should be an easier way to do this/ function I'm unaware of. Any ideas other than more specific classes/ids on more elements?
Basically, my question boils down to accessing the div with id outer
when I have a reference to the span with id 'innerSpan' in the html below:
<div id='outer'>
<a href="some_url">
<span id="inner">bla bla</span>
</a>
</div>
So currently, I would do something like this:
var outer = $('#inner').parent().parent()
and that gets crazy with deeply nested elements.
Another example:
Here my html:
<div id="options_right">
<table id="product_options_list" class="table table-bordered">
<tbody id="1">
<tr>
<td>
<select name="option_1_val[0]" class="option_table_select">
<option value="Red">Red</option>
<option value="Blue">Blue</option>
<option value="Green">Green</option>
</select>
</td>
<td>
<table class="table sub_options" id="0">
<tbody>
<tr>
<td>
<select name="option_1_sub[0][]" class="option_table_select sub_option_select">
<option value="">None</option>
<option value="2">Size</option>
</select>
<div class="sub_option_value_holder">
<select name="option_1_sub_val[0][]" class="sub_option_values" style="display:none;"></select>
</div>
</td>
<td>
<a href="#" class="remove_sub_option btn btn-primary">Remove</a>
</td>
<td>
<a href="#" class="add_sub_option btn btn-primary">Add Another</a>
</td>
</tr>
</tbody>
</table>
</td>
and my script. i wrote a function and need to pass it the ids of the main rows tbody as well as the secondary tables id so i can dynamically add more rows. You don't really need that function for this question but basically i get those ids like so:
get_suboption_row($(this).parent().parent().parent().parent().parent().parent().parent().attr('id'), $(this).parent().parent().parent().parent().attr('id'));
thanks
jsFiddle: http://jsfiddle.net/Hg4rf/
click the add another to trigger event
Upvotes: 36
Views: 80853
Reputation:
The best way is to use eq() after the parents() function
get_suboption_row($(this).parents().eq(7);
Upvotes: 0
Reputation: 206344
You have 2 nested tables,
to get what you want you can use this two DOM traversal methods .closest()
or .parents()
.closest()
Self or ancestor. Self or travels up the DOM tree until it finds a match for the supplied selector.parents()
Travels up the DOM tree to the document's root element, adding each ancestor element to a temporary collection; it then filters that collection based on a selector if one is supplied
Using nested tables:
$(this).closest('table').closest('tbody').attr('id');
$(this).parents('table').parents('tbody').attr('id');
Upvotes: 56
Reputation: 218832
If you know the CSS Class name
for that element, you can call the closest()
method
var thatParent= $("#someId").closest(".somCSSClassName")
So your code cal be rewritten as
get_suboption_row($(this).closest("someClass").attr('id'),
$(this).closest("someOtherClass").attr('id'));
EDIT : After seeing your JSfiddle
Use the class name to get the Parent Table.
alert($(this).closest('tbody').closest('.table-bordered').attr('id'));
Working sample : http://jsfiddle.net/Hg4rf/2/
Upvotes: 4