Question

I'd like to detect if the selection option is under the 'international' optgroup. Right now my approach is to detect the closest optgroup from the selected item, and get the contents of its label attribute. I could test that string for the word 'international'. Other approaches are more then welcome.

As you can tell, from this markup its unfortunate that the optgroup doesn't wrap the child options:

<select id="venue">
    <optgroup label="New England"></optgroup>
        <option value="1">&nbsp;NH</option>
        <option value="2">&nbsp;ME</option>
        <option value="3">&nbsp;VT</option>
        <option value="4">&nbsp;MA</option>   
        <option value="4">&nbsp;CT</option>   
        <option value="4">&nbsp;RI</option>   
    <optgroup label="International"></optgroup>
        <option value="100">Canada</option>
        <option value="100">Texas</option>
        <option value="100">Mexico</option>
</select>

The jQuery I've been working with obviously wont work, but you can see where I am trying to get to:

dropdownval = jQuery('select#venue option:selected')
    .parentsUntil( jQuery('optgroup'), '[label*="international"]')
        .attr('label');`

EDIT

Its been pointed out to me that the following nesting of optgroups is also possible

<select id="venue">
    <optgroup label="New England"></optgroup>
        <option value="1">&nbsp;NH</option>
        <option value="2">&nbsp;ME</option>
        <option value="3">&nbsp;VT</option>
        <option value="4">&nbsp;MA</option>   
        <option value="4">&nbsp;CT</option>   
        <option value="4">&nbsp;RI</option>   
    <optgroup label="International"></optgroup>
        <option value="100">&nbsp;Canada</option>
        <option value="100">&nbsp;Texas</option>
        <option value="100">&nbsp;Mexico</option>
    <optgroup label="&nbsp;Europe"></optgroup>
        <option value="100">&nbsp;&nbsp;Bruges</option>
</select>
Was it helpful?

Solution

If your list is dependably ordered (as presented), then you can skip catching the relationship, ie first(), etc, and follow .prevAll('optgroup') all the way up. But if the order of your options might change, try .nextAll('optgroup'), or follow @Barmar's logic to traverse in the direction needed:

$("#venue").change(function() {
    $("#venue option:selected").each(function() {
        if ($(this).prevAll('optgroup').attr('label') == 'International') {
            alert('detected');
        }
    });
});

http://jsbin.com/ibIJezO/1/

OTHER TIPS

if ($('#venue option:selected').prevAll('optgroup').first().is('[label*="International"]'))
    ...
}

.prevAll('optgroup') gets all the preceding optgroups. .first restricts it to the first one, which is the closest preceding optgroup. Then .is() tells you if its label matches your criteria.

JSBIN

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top