jQuery to go to an optgroup label
Asked Answered
E

2

6

I have a dropdown setup for searching. The idea is you click one option, Then the OPTGROUP appears. What I'd like to do is once the label is selected it jumps to that section of the OPTGROUP.

I have written some jQuery so far. See this jsFiddle - So once you select a main category. I would like the optgroup to go to its paired label. How can I achieve this?

HTML

<select id="category" name="category">
 <option selected="selected" value="0">Choose a category...</option>
 ...
 <option value="4">Photography</option>
</select>
<select multiple="multiple" id="subcategory" name="category_ids[]">
<optgroup label="Art Styles">
 <option value="5">Abstract</option>
 ...
 <option value="18">Graphics</option>
</optgroup>
<optgroup label="Art Subjects">
 <option value="19">Animals</option>
 ...
 <option value="45">Dreams &amp; Nighmares</option>
</optgroup>
<optgroup label="Media">
  <option value="46">Water Colour</option>
  ...
  <option value="56">Mixed Media</option>
</optgroup>
<optgroup label="Photography">
 <option value="57">Color Photography</option>
 ...
 <option value="64">Celebrity Photography</option>
</optgroup>

Portrait Landscape Square

JavaScript

// Search Options Dropdown

// Hide Subcategory Dropdown

$('#subcategory').css('display', 'none');

// Hide Orientation Dropdown

$('#orientation').css('display','none');

$('#category').change(function()
{
    $('#subcategory').css('display', 'block');
    $('#orientation').css('display', 'block');

    var CatValue = $("#category").val();

    if (CatValue == '1')
    {

    }
});
Enjoy answered 7/6, 2012 at 11:9 Comment(12)
You should replace your css() calls by simple show() and hide(), without additional arguments. Even if just for readability.Peafowl
@StefanMajewsky - Noted. I've followed that nowEnjoy
Very dirty hack: jsfiddle.net/aNhzY/2. Works in Chrome, but I'm sure there's a better way.Celenacelene
Nice, But option value 2,3 and 4 in FireFox load up alot further down their label.Enjoy
Hm, it appears Firefox adds a 1px vertical padding in the select box. You'd need - 1 instead of + 1, but this would require browser sniffing.Celenacelene
Add some reference id to each option group and then move to select the first child of your choice $("#"+CatValue+" option:first").attr("selected", "selected");Qadi
Just a note - according to this there is visually no <option> element. So I'm not sure if it actually makes sense semantically to "move to an optgroup".Celenacelene
you can select the first element FiddleQadi
@Alex Ball: Chrome doesn't scroll automatically when selecting an option.Celenacelene
@pimvdb, i'm sorry, i've not tested, just the ideaQadi
I'm thinking its a stupid way of going about things now. I'm thinking of doing a seperate DB query to select 4 seperate lists and just show them based on the value of the first selection to load in the list.Enjoy
@Stu Blackett: Sounds like a better user experience. Currently the first select is more or less redundant, and you can choose any category item in select #2 regardless of what you chose in select #1.Celenacelene
N
1

Well, it feels a bit hacky, but it works in Chrome, and I am sure with a little browser sniffing and determining option item heights in each browser you could get it working in all of them:

// Search Options Dropdown
// Hide Subcategory Dropdown
$('#subcategory').css('display', 'none');
// Hide Orientation Dropdown
$('#orientation').css('display', 'none');
$('#category').change(function() {
    var cat = $("#category :selected").text();
    var $subcat = $('#subcategory');
    $('#orientation').css('display', 'block');
    var optcount = 0;
    var optheight = 17;
    $subcat.css('display', 'block').find('optgroup').each(function() {
        optcount++;
        if ($(this).attr('label') == cat) {
            $subcat.val($('#subcategory optgroup[label="' + $(this).attr('label') + '"]').children('option:first').val())
                .scrollTop($('#subcategory :selected')[0].index * optheight + ((optcount - 1) * optheight));
        }
    });
});​

jsfiddle

I am sure there is a little cleanup you could do too - like move optgroup++ and remove the - 1 from scrollTop - ewww. It should get you pointed in the correct direction at least.

Neotype answered 7/6, 2012 at 13:11 Comment(0)
A
1

I took Tims answer and improved that further. It will no longer select the first item to prevent wrong Multiselectbox behavior and scrolls to first Optgroup child instead of the (no longer) selected child. I also removed the counting variable using index and determined the option height based on parents size attribute (breaks with custom css heights).

$('#category').change(function() {
    var cat = $("#category :selected").text();
    var $subcat = $('#subcategory');
    var optheight = $subcat.height() / $subcat.attr('size');
    $subcat.find('optgroup').each(function(index) {
        $optgroupFirstChild = $('#subcategory optgroup[label="' + $(this).attr('label') + '"]').children('option:first');
        if ($(this).attr('label') == cat) {
          $subcat.scrollTop($optgroupFirstChild[0].index * optheight + (index * optheight));
        }
    });
});

jsfiddle

Accordion answered 14/7, 2017 at 8:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.