1

Target: From a select dropdown menu, if someone selects an option, disable/remove/hide the rest of the options on that dropdown menu.

Here is the dropdown menu. If someone selects "1", the rest of options (2,3,4) will be removed/disabled/hide:

<div class="abc">
  <div class="xyz">
    <select name="pqr" class="selectDropdown">
      <option value='1'>1</option>
      <option value='2'>2</option>
      <option value='3'>3</option>
      <option value='4'>4</option>
    </select>
  </div>
</div>

Here is the JavaScript I tried to use:

$('.selectDropdown').on('change', function(e) {
    $(this).closest('.abc').children('.xyz').children('option:not(:selected)').prop('disabled', true);
});

I know, the JavaScript is faulty here. Where did I make the mistake?

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
crazymoin
  • 336
  • 3
  • 13

4 Answers4

3

Keep it simple and use:

$('.selectDropdown').on('change', function(e) {
    $(this).children('option:not(:selected)').prop('disabled', true);
});

In this context, $(this) refers to .selectDropdown and the option elements are the children.

Example Here


..and if you want to remove the unselected children:

$('.selectDropdown').on('change', function(e) {
    $(this).children('option:not(:selected)').remove();
});

Example Here


The reason your code wasn't working was because the option elements are not direct children of the .xyz element. You would have had to use:

$('.selectDropdown').on('change', function(e) {
    $(this).closest('.abc').children('.xyz').children().children('option:not(:selected)').prop('disabled', true);
});

(I simply chained another .children() method after .children('.xyz')..)

Josh Crozier
  • 233,099
  • 56
  • 391
  • 304
2

You're over complicating it. Once the user has clicked on the select box, you're inside that selector so there's no need to go up to .abc and .xyz.

Here's a fiddle to show it working in action: http://jsfiddle.net/releaf/ng50zmyo/

$('.selectDropdown').on('change', function(e) {
 $(this).find('option:not(:selected)').prop('disabled', true);
});
ReLeaf
  • 1,368
  • 1
  • 10
  • 17
1

This simplifies things. Since this is the select no need to traverse up 2 levels and back down to get back to where you started again

$('.selectDropdown').on('change', function(e) {
    $(this).children(':not(:selected)').prop('disabled', true);
});

if remove is preferred swap out prop() for remove()

$('.selectDropdown').on('change', function(e) {
    $(this).children(':not(:selected)').prop('disabled', true);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="abc">
  <div class="xyz">
    <select name="pqr" class="selectDropdown">
      <option value='1'>1</option>
      <option value='2'>2</option>
      <option value='3'>3</option>
      <option value='4'>4</option>
    </select>
  </div>
</div>
charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

You just select wrong node. $(this).closest('.abc').children('.xyz') --> this node's childs point to select, which has no child node option.

Here you go:

$('.selectDropdown').on('change', function(e) {
    $('select[name="pqr"]').children('option:not(:selected)').prop('disabled', true);
});

JSFiddle

Đức Nguyễn
  • 606
  • 3
  • 9
  • 19
  • 2
    why change selectors? that seems confusing when you are targeting the exact same element – charlietfl Jan 27 '15 at 01:42
  • 1
    Agreed. There's no reason to query the DOM again here when $(this) is already in context. – ReLeaf Jan 27 '15 at 01:49
  • I just want to crarify the correct selector. @crazymoin select the wrong node because he travels up to `'.abc'` and then tralvels down. Instead of solving the "example", why not point out the correct selector? – Đức Nguyễn Jan 27 '15 at 01:59
  • 1
    but suppose there were 10 of this class in a page. the inner selector may not even be the right one, whereas `this` will always be the element that event occured on and is more readable as well – charlietfl Jan 27 '15 at 02:20