tags:

views:

73

answers:

5
$country.parent().parent().next().children('td').children('.province-select')

Basically I have some HTML that looks like this:

<table>
    <tr>
        <th>country</th>
        <td><select name="country"/></td>
    </tr>
    <tr>
        <th>province</th>
        <td><select class="province-select"/></td>
    </tr>
</table>

Once I've nabbed the country select, I need to find the next .province-select. Would be nice if it's little more robust to subtle HTML changes.

AFAIK next() only finds siblings, and closest() only traverses up the DOM tree.


I have a few of these all in the same table. That's why I'm using all this parent/next garbage. I don't want to use IDs because... well, then the script will only work on one specific country/province pair; I need it to run on all of them; thus I need to find the corresponding province field for the country field.

+2  A: 

You could try

$country.parents( 'tr' ).next().find('.province-select')

hookedonwinter
This will only find it if the next sibling has a select, what if he includes a blank tr with a subtle change;)
redsquare
My 2nd favourite answer. I think `closest` stops when it hits the first `tr`, whereas `parents` will keep going up, even though it won't find any, because that'd be a messed up table! Unless it were a table in a table..then it would get screwed up.
Mark
+3  A: 

For example:

$contry.closest('tr').next('tr').find('> td > .province-select')
Felix Kling
This will only find it if the next sibling has a select, what if he includes a blank tr with a subtle change;)
redsquare
I like this one. It's nice, clean, pretty efficient. I'd leave out the `> td >` bit though. Thanks!
Mark
+2  A: 

Below is ugly but will account for 'subtle' changes like adding extra tr's in between the two selects, it also accounts for multiple country/province pairs of select elements.

//cache closest tr so we can get its index and use it as the base for the next traversal
var $closesttr = $country.closest('tr');

//search the tbody  for the first instance of an element that has the class
// province-select and is after the tablerow that contains the current country

$closesttr.parent()
          .find('tr:gt(' + $closesttr.index() + ') .province-select:first');
redsquare
This does what I asked... but I think I put a little too much emphasis on the "robustness". More concerned about simplicity... robustness was a secondary concern. Much appreciated answer though :) Will refer back to this if indeed my form changes that much.
Mark
+1  A: 

I would probably go with:

$country.closest('table').find('.province-select');
William
You should use `.closest()` here, if the `<table>` is nested for example this can have undesired results.
Nick Craver
Thanks Nick, good point.
William
But this will find all elements (in the table) with the class, not just the next one from his current element. Unless I am reading the OP wrongly.
redsquare
I think @redsquare is right. Question seems to imply multiple elements with `.province-select` in the table.
patrick dw
@redsquare/patrick: You're right. Updated Q.
Mark
+1  A: 

if you can add IDs to your selects

$('#country') and $('#province-select') will get your elements, that's assuming your HTML isn't inside a repeater/list of some kind

Edit:
hmm, in that case have you tried the equivalent of GetElementsByName?

Antony Scott
Except that it is ;) Sorry !
Mark
re: edit: Not sure how that helps... they *do* have unique names, but I still need to find the closest one.. I don't want to write the same thing three times so that I can use IDs/names. Needs to be a general sol'n.
Mark
my mistake, it was late and i was bleary eyed. i get what you want now.
Antony Scott