0

I have a Multi-Select where one option must be exclusive:

  1. If it gets selected, any other prior selections in the Multi-Select are deselected
  2. If another option gets selected while it is selected, this option is deselected

I was trying to examine the just-selected option, but .val() gives me the overall selection.

$('#educationLevel').on('change', function(e) {
    var selection = $(e.target).val();
    // This gives overall selection, not the just-selected one for my checks
}

Any tips?

gene b.
  • 10,512
  • 21
  • 115
  • 227
  • On a multi select `val()` returns an array. Check what's in the array – charlietfl Feb 01 '22 at 01:37
  • I can't. I need to know what has *just* been selected *individually*. I can't just say that if the array contains my value, then force it to my value. If that's the case, I'll never exit the exclusive-option condition. Do you understand what I mean? – gene b. Feb 01 '22 at 01:41
  • I understand that you can either have only that one specific value or a combination of any of the others. Is that not correct? – charlietfl Feb 01 '22 at 01:50
  • That's correct. But if that one specific value is selected, I won't be able to select anything else afterwards, and I should be able to. That's why I can't ask "does my array include this value." Are you saying that the *order* of the items in the array can tell me the latest-added item? – gene b. Feb 01 '22 at 01:52
  • Sure you can. You can splice the array and set the updated value of the select – charlietfl Feb 01 '22 at 01:53
  • Care to demonstrate with a snippet? Are you saying the order tells me which one is last-added? – gene b. Feb 01 '22 at 01:53
  • Order shouldn't matter. You either have the exclusive value in the array or you don't – charlietfl Feb 01 '22 at 02:11

1 Answers1

0

There's a similar thread here, Mutual exclusion for <option>s in a <select>? . We need to keep track of the current selection array and diff it with the latest selection array. This will tell us what has just been selected.

Solution:

// Global Var:
// To implement an exclusive option in a MultiSelect dropdown,
// we need to keep track of the current selection (a global var here) 
// and diff this array with the latest selection array in change() event.
var currSel = $('#educationLevel').val();

// Change Event Definition
$('#educationLevel').on('change', function() {
    var newSel = $(this).val();
    // Get diff from currSel; a 1-element array expected.
    // Diff in arrays: see: https://stackoverflow.com/a/33034768/1005607
    var diff = newSel.filter(x => !currSel.includes(x));
    // If exclusive option just got selected, delete all others
    if (diff.length) {
        if (diff[0] === '405') { // '405' is my exclusive option
           // If exclusive option just got selected ("405"), deselect all others 
           // in modified selection array
           newSel = ['405'];
        } else {
           // If non-exclusive option just got selected, ensure that the exclusive option 
           // is not in the modified selection array
           newSel = newSel.filter(el => el !== '405');
        }
        // Set dropdown to the modified new selection array
        $('#educationLevel').val(newSel);
    }
    // Clone latest selection array into current selection array
    currSel = [...newSel];
}
gene b.
  • 10,512
  • 21
  • 115
  • 227