9

I've put 2 elements next to eachother. Both of them are using the jQuery Chosen plugin.

This is the code:

<div class="wrapper">
  <select data-placeholder="Number row 1" style="width:350px;" multiple class="chzn-select">
    <option value=""></option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
  </select>

  <select data-placeholder="Number row 2" style="width:350px;" multiple class="chzn-select">
    <option value=""></option>
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
    <option value="4">4</option>
    <option value="5">5</option>
    <option value="6">6</option>
  </select>
</div>

This is the Javascript. jQuery library, the latest Chosen plugin and CSS are all properly included ofcourse.

<script>
$('.chzn-select').trigger("liszt:updated");
$('.chzn-select').chosen().change( function() {
  var selectedValue = $(this).find('option:selected').val();
  $(this).parent().find('option[value="'+ selectedValue +'"]:not(:selected)').attr('disabled','disabled');
});
</script>

This is what I want to accomplish with the script above.

  • There are two select elements with the same values. When value "1" has been selected in element 1 for example, I want to disable it in element 2.
  • However. after I deselect value "1" in element 1, it's still disabled in element 2. That's not what I want. The other value should be available again after deselecting the value in the 1st element.

Does anybody know how to accomplish this?

I've put up a JSFiddle here: http://jsfiddle.net/dq97z/3/

Daniel Widdis
  • 8,424
  • 13
  • 41
  • 63

4 Answers4

24

Something like this should do it:

http://jsfiddle.net/musicisair/dq97z/10/

// cache selects for use later
var selects = $('.chzn-select');

// whenever the selection changes, either disable or enable the 
// option in the other selects
selects.chosen().change(function() {
    var selected = [];

    // add all selected options to the array in the first loop
    selects.find("option").each(function() {
        if (this.selected) {
            selected[this.value] = this;
        }
    })

    // then either disabled or enable them in the second loop:
    .each(function() {

        // if the current option is already selected in another select disable it.
        // otherwise, enable it.
        this.disabled = selected[this.value] && selected[this.value] !== this;
    });

    // trigger the change in the "chosen" selects
    selects.trigger("liszt:updated");
});
David Murdoch
  • 87,823
  • 39
  • 148
  • 191
  • Doesn't work either. When I have selected value "2" in 1 menu, it's still visible in the other one. – Martijn van Turnhout Feb 08 '12 at 07:27
  • Ah, I didn't notice you required multiple selects. I'll fix this as soon as jsfiddle comes back online. – David Murdoch Feb 08 '12 at 14:37
  • This is just awesome. Clean coding and understandable. Two thumbs up! – Martijn van Turnhout Feb 09 '12 at 07:17
  • Could you explain this line please? `this.disabled = selected[this.value] && selected[this.value] !== this;` I understand you put the selected options in an array in the first loop and in the second loop, you disable every option if the value is already in that "selected" array. But what does `&& selected[this.value] !== this` stand for? – Martijn van Turnhout Feb 09 '12 at 07:56
  • The first loop stores a reference to the actual option's DOM node. So, the value of `selected[this.value]` is the DOM node of the *selected* option - and we don't want to disable the selected option. If `selected[this.value]` exists and the value of `selected[this.value]` is NOT the selected option, disabled it. – David Murdoch Feb 09 '12 at 14:47
  • 2
    @DavidMurdoch thanks for the script. For updated version use selects.trigger("chosen:updated"); – Umar Adil Feb 07 '14 at 11:20
  • hi all , anyone know how to maintain the select order , http://stackoverflow.com/questions/25266287/how-to-maintain-the-selected-order-of-chosen-and-pass-the-value-by-selected-orde – Dhanush Bala Aug 13 '14 at 13:35
2

I'm trying to use this code without the multiple choice so for each select only one option can be chosen. I want to use the allow_single_deselect: true code to remove an option if chosen in the select box but I can't get it working. I disabled the search option because I don't need it on this page.

<script>//<![CDATA[ 
$(function(){  
$('.chzn-select').chosen({disable_search_threshold: 10}) .change(
function() {
var selectedValue = $(this).find('option:selected').val();
$(this).parent().parent().find('option[value="'+ selectedValue +'"]:not(:selected)').attr('disabled','disabled');
$('.chzn-select').trigger("liszt:updated");
});

});//]]></script>       
Stefannno
  • 21
  • 1
0

Since you are modifying the option which is selected in the first dropdown the previous options which were disabled are not enabled again.

You need to first enable all the options and then disable only the selected option. Try this

$('.chzn-select').trigger("liszt:updated");
$('.chzn-select').chosen().change( function() {
    var selectedValue = $(this).find('option:selected').val();
    var $options = $(this).parent().find('option').attr('disabled', false);
    $options.filter('option[value="'+ selectedValue +'"]:not(:selected)')
    .attr('disabled', true);
});
ShankarSangoli
  • 69,612
  • 13
  • 93
  • 124
  • I've emptied my cache and hard refreshed the page, but this approach doesn't work either. I want to select value "3" for example in the 1st menu and immediately after that, value "3" in the 2nd menu should be disabled. – Martijn van Turnhout Feb 08 '12 at 07:30
0

You set the disabled on every change, ofcourse it won't work...

In this code I change the disabled attribute based on the previous value;

<script>
$('.chzn-select').trigger("liszt:updated");
$('.chzn-select').chosen().change( function() {
  var selectedValue = $(this).find('option:selected').val();
  $(this).parent().find('option[value="'+ selectedValue +'"]:not(:selected)')
        .prop("disabled", function( i, val ) {
              return !val;
            });
});
</script>
gdoron
  • 147,333
  • 58
  • 291
  • 367