How to update select2 list as soon as select list is updated


#1

I am updating select list option on onchange event. That means if an option is selected in dropdwon1 I want to hide that particular option in other remaining dropdowns. This feature is already achieved in general html select but unable to achieve it in select2. My code which is working for general select.

var d_array = Array();
$(document).ready(function(){


    $('.mselect').on("change", function (e) {

      d_array = [];

      $('.mselect').each(function(k,v){

        cv = $(this).val();
        
        if($.trim(cv) != '')
        {
            d_array.push(cv);
        }

    });

      checkMSelect2();
      $('.select2').select2();

  });

});

function checkMSelect2()
{

    $('.mselect').each(function(k,v){

        c = $(this);
        cv = c.val();

        c.find('option').show();

        $(d_array).each(function(ki, vi){
            if(vi != cv)
            {
                c.find('option[value="'+vi+'"]').hide();
                
            }

        });

    });


}

Ask if you need any further explanation.


#2

With the Select2 widget, you have to “notify” the widget whenever the underlying <option>s are changed. The Select2 documentation discusses this in the context of adding new items, but the same applies to removing them.

However, looking at your code again, it looks like you just want to hide the selected option in the other Select2s, not actually delete them. In that case, I’m pretty sure Select2 doesn’t pay any attention to the hidden state of the underlying <option> elements. In the rendered Select2 widget’s dropdown, the items are rendered as an unordered list. Theoretically you could hide those <li> elements instead, but my experience is that it’s hard to figure out which <li> is associated to the item you want to hide.

Since the <li>s should be in the same order as the <option>s in the underlying <select>, you might be able to keep track of the index of the matching <option>s and hide the equivalent <li>. However, an easier (and better supported) approach might be to use a custom templateResult function on the Select2(s) where you want to hide the item selected from the other Select2. The idea would be to store the selected item’s value in a variable that the custom templateResult function would use to compare with each item in the second Select2’s result list, and return “null” for the matching item. That will remove the item from the rendered dropdown without actually removing its data from the widget (or the underlying <select>.