Rooster
Rooster

Reputation: 10077

More efficient way to do parent().parent().parent() etc. in jquery

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

Answers (4)

user16662240
user16662240

Reputation:

The best way is to use eq() after the parents() function

get_suboption_row($(this).parents().eq(7);

Upvotes: 0

Roko C. Buljan
Roko C. Buljan

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');

jsFiddle demo

Upvotes: 56

Andy
Andy

Reputation: 30135

I think .closest() is what you're looking for :)

Upvotes: 7

Shyju
Shyju

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

Related Questions