Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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>', {value: value, selected: selected, text: text});
}
});
});
@alex-jitbit

This comment has been minimized.

Copy link

commented Nov 9, 2018

thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.