1

I have 4 select boxes, each containing the exact same data:

  • Riding
  • Fishing
  • Smoking
  • Flying

If I'm in select-box[0] and select "Riding", I want to remove the option from each of the remaining except the current select-box I have active.

I've tried select:not(:first-child) but this will remove, only if the first child is the selection, not any of the other.

Basically, I need to remove a selected option from all drop-downs except the one I made the selection on.

JadedEric
  • 1,943
  • 2
  • 26
  • 49
  • Do you need to add them back if the option changes? – Andy E Feb 02 '12 at 12:16
  • possible duplicate of [Prevent Multiple Selections of Same Value](http://stackoverflow.com/questions/4001805/prevent-multiple-selections-of-same-value) – Felix Kling Feb 02 '12 at 12:16
  • Andy E, most likely yes. But I'm sure I'd be able to reverse the steps to add the item back in, store the value that was removed somewhere, like a hidden field or something, add it back and replace the value of the newly removed item. – JadedEric Feb 02 '12 at 12:30
  • @FelixKling it's not a duplicate - that question wants to _disable_ the duplicates, this one wants to _remove_ them. – Alnitak Feb 02 '12 at 12:37
  • 1
    @Alnitak: The other question also mentions to remove an option. Conceptionally, both questions are the same. And from UX perspective, maybe disabling the other options only is better anyway. It should not be that hard to adjust the solution if removal is really needed. – Felix Kling Feb 02 '12 at 12:42

2 Answers2

5

Try this:

$('#select1').on('change', function() {
    var val = this.value;
    $('select').not(this).children().filter(function() {
        return this.value === val;
    }).remove();
});

i.e. for every <select> that is not this, get its children, but filter the ones whose .value is not the same as mine, and remove them.

Working demo at http://jsfiddle.net/alnitak/CJYWn/

If you need to re-add elements when the first entry is changed to something else, you might consider just cloning the entire first select whilst filtering out the unwanted items.

In this case the filter would need !==, since we want all of the elements except the one that matches, i.e.

$('#select1').on('change', function() {
    var val = this.value;
    $('select').not(this).empty().append($(this).children().filter(function() {
        return this.value !== val;
    }).clone());
});

working demo at http://jsfiddle.net/alnitak/ARUmX/

Alnitak
  • 334,560
  • 70
  • 407
  • 495
  • I think you're making this a little overly complex. Specifying `.children('option')` could simply be `.children('[value=' + val + ']')`. No need to specify `option` as the tag within `.children()`, and using the attribute equals selector you can avoid having to use `filter`. – maxedison Feb 02 '12 at 12:23
  • @maxedison as a matter of principle I don't use string concatenation in selectors, it's unsafe. – Alnitak Feb 02 '12 at 12:27
  • 1
    @Alnitak would you mind elaborating on why string concatenation would be unsafe in this manor with and example maybe? – Craig Feb 02 '12 at 12:43
  • @Craig if (for example) one of the option values contained a quotation mark the resulting selector would be invalid because it would contain unbalanced quotation marks. In this particular case he's OK, but IMHO it's better to program around potential unsafe options in case those are added later. – Alnitak Feb 02 '12 at 13:12
  • @Alnitak agreed, thanks. thought you might have been aware of other potential issues...but I do agree with your logic. thanks – Craig Feb 02 '12 at 13:56
0

There is also the .not() method as well as the selector.

http://api.jquery.com/not/

From the docs:

.not( function(index) )

function(index)A function used as a test for each element in the set. this is the current DOM element.

hollsk
  • 3,124
  • 24
  • 34