JSFiddle - React, Tailwind, and code Playground
by potatosalad
HTML
<select id="bandmembers" multiple="multiple" size="10">
<optgroup label="Queen">
<option value="Mercury">Freddie</option>
<option value="May">Brian</option>
<option value="Taylor">Roger</option>
<option value="Deacon">John</option>
</optgroup>
<optgroup label="Pink Floyd">
<option value="Waters">Roger</option>
<option value="Gilmour">David</option>
<option value="Mason">Nick</option>
<option value="Wright">Richard</option>
</optgroup>
</select>
JavaScript
// Detect toggle key (toggle selection)
$('select')
.on('mousedown', function(event) {
// toggleKey = Command for Mac OS X; Control for others
var toggleKey = (!event.metaKey && event.ctrlKey && !(/Mac OS/.test(navigator.userAgent))) ? event.ctrlKey : event.metaKey;
if (toggleKey === true) {
$(this).data('toggleKey', true);
}
$(this).data('_mousedown', true);
})
.on('mouseup', function() {
$(this).data('_mousedown', null);
});
// Chrome fix for mouseup outside select
$(document).on('mouseup', ':not(select)', function() {
var $select = $('select');
if ($select.data('_mousedown') === true) {
$select.data('_mousedown', null);
$select.trigger('change');
}
});
$('select')
.on('focus', storeState)
.on('change', changeState);
function storeState() {
$(this).data('previousGroup', $('option:selected', this).closest('optgroup'));
$(this).data('previousVal', $(this).val());
};
function changeState() {
var select = this,
args = Array.prototype.slice.call(arguments);
var previousGroup = $(select).data('previousGroup'),
previousVal = $(select).data('previousVal');
var currentGroup = null,
currentVal = $(select).val();
var selected = $('option:selected', select),
groups = selected.closest('optgroup');
console.log("[change] %o -> %o", previousVal, currentVal);
if ((previousVal === currentVal) && (groups && groups.length == 1)) {
// selected options have not changed
// AND
// only 1 optgroup is selected
// -> do nothing
} else if (currentVal === null || currentVal.length === 0) {
// zero options selected
// -> store state and do nothing
storeState.apply(select, args);
} else { // a select/deselect change has occurred
if ($(select).data('toggleKey') === true
&& (previousVal !== null && previousGroup...