Skip to content

Instantly share code, notes, and snippets.

@skanev
Created August 11, 2011 13:35
Show Gist options
  • Select an option

  • Save skanev/1139663 to your computer and use it in GitHub Desktop.

Select an option

Save skanev/1139663 to your computer and use it in GitHub Desktop.
Convert a <select> with <optgroups> to two <select>s that are interconnected

If you have a select with option groups:

<select data-nested-select="Select country">
  <option>Select city</option>
  <optgroup label="Bulgaria">
    <option value="sofia">Sofia</option>
    <option value="plovdiv">Plovdiv</option>
  </optgroup>
  <optgroup label="Sweden">
    <option value="stockholm">Stockholm</option>
    <option value="uppsala">Uppsala</option>
  </optgroup>
</select>

This jQuery snippet will convert it to two separate 's -- one for country and one for city. Whenever the user changes the country, the other will display only the cities that are in that country.

$(function() {
$('select[data-nested-select]').each(function() {
var select = $(this),
groupName = select.data('nested-select'),
optgroups = select.find('optgroup'),
options = select.find('optgroup option'),
groupSelect = $('<select>'),
promptOption = makeOption(groupName, null, false);
groupSelect.
append(promptOption).
insertBefore(select);
optgroups.each(function(index) {
var optgroup = $(this),
name = this.label,
children = optgroup.children(),
selected = children.is(':selected'),
groupOption = makeOption(name, index, selected);
groupOption.data('options', children);
groupSelect.append(groupOption);
optgroup.detach();
});
groupSelect.change(function() {
var optionsInGroup = groupSelect.find('option:selected').data('options') || [],
hiddenOptions = options.not(optionsInGroup);
hiddenOptions.
attr('selected', false).
detach();
select.append(optionsInGroup);
});
groupSelect.change();
function makeOption(text, value, selected) {
return $('<option>').
attr('value', value).
attr('selected', selected).
text(text);
}
});
});
@edzhelyov
Copy link
Copy Markdown

Hm, forking this gist doesn't work :/

You can at least do the DOM manipulations at once. I couldn't find a way to replicate the hiddenOptions behavior, but you can easily insert the groupSelect after all modifications have been made, this way you will trigger only one DOM repaint.

see https://gist.github.com/1140062

@skanev
Copy link
Copy Markdown
Author

skanev commented Aug 11, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment