33

I have select2 multi select field in my form where I want to remove the selected option from the dropdown list after it is selected and again add it to the list if it is removed from the list. And also the added items should be in the same order as they selected. The current select2 (4.0) is not removing the selected the items and and it is showing the selected items in the order they appear in the drop down list, not in the order they are selected.

$(document).ready(function(){
    $('#dynamicAttributes').select2({
            allowClear: true,
            minimumResultsForSearch: -1,
            width: 600
     });
 });

JSFiddle: https://jsfiddle.net/rd62bhbm/

BoltClock
  • 630,065
  • 150
  • 1,295
  • 1,284
user1614862
  • 2,751
  • 6
  • 21
  • 35

8 Answers8

82

Part #1 of Q:

You can do a CSS trick to hide selected item like this:

.select2-results__option[aria-selected=true] {
    display: none;
}

Part #2 of Q:

Also you can do a JQuery trick to force selected items to end of tags box, ( by getting selected item on select, detach it (remove it), then reAppend it to tags box, then call "change function" to apply changes ):

$("select").on("select2:select", function (evt) {
    var element = evt.params.data.element;
    var $element = $(element);
    $element.detach();
    $(this).append($element);
    $(this).trigger("change");
});

Finally Updated JsFiddle, I hope it works for you, Thanks !

Edit #1

You can Clear All Selected by this call (apply Null values):

$("#dynamicAttributes").val(null).trigger("change"); 

on Button:

$('#btnReset').click(function() {
    $("#dynamicAttributes").val(null).trigger("change"); 
});

Updated Fiddle #2

Shady Alset
  • 4,850
  • 3
  • 19
  • 31
  • It just clears all the selected values from input box, but not triggering unselect event ".on('select2:unselect', function(e) {}". It happens when I actually click on "x" button on the input box. I want the similar behavior when I click on form's reset button. Because I have some code to get executed on unselect callback function for every selected value. – user1614862 Apr 18 '16 at 08:36
  • @user1614862 yes this method not triggering unselect event. this triggering method is officially used in plugin documentation > [Programmatic access](https://select2.github.io/examples.html#programmatic).. but i will notifying you as soon as i found another method. Thanks – Shady Alset Apr 18 '16 at 16:35
  • 5
    Unfortunately the part#1 CSS solution doesn't work well when going through the options using a keyboard, because it still traverses the `display: none` ones. – Koby Apr 24 '18 at 10:45
  • **Part #1** is enough for me :) thank you – Espresso Apr 05 '21 at 16:08
3

I find a way to make the selected values not to appear anymore on the selection pop up list

On the documentation you can they have list of events Select2 events

open

I make use of these select2 event open to hide the selected values

Here is the javascript ::

$(document).ready(function() {

  $('#dynamicAttributes').select2({
      allowClear: true,
      minimumResultsForSearch: -1,
      width: 600
  });

  // override the select2 open event
  $('#dynamicAttributes').on('select2:open', function () {
    // get values of selected option
    var values = $(this).val();
    // get the pop up selection
    var pop_up_selection = $('.select2-results__options');

    if (values != null ) {
      // hide the selected values
       pop_up_selection.find("li[aria-selected=true]").hide();

    } else {
      // show all the selection values
      pop_up_selection.find("li[aria-selected=true]").show();
    }

  });

});

Here is a DEMO

Hope it helps.

Oli Soproni B.
  • 2,938
  • 3
  • 19
  • 45
2

my solution was modified the select2.js (the core, version 4.0.3) in the line #3158. Add the following verification :

if ($option[0].selected == true) {
      return;
}

With this verification, we can exclude from the dropdown list, the selected ones. And if you write the name of a selected option, appear the text of option "noResult" .

Here the complete code:

SelectAdapter.prototype.query = function (params, callback) {
    var data = [];
    var self = this;

    var $options = this.$element.children();

    $options.each(function () {
      var $option = $(this);    
      if (!$option.is('option') && !$option.is('optgroup') ) {
        return;
      }

      if ($option[0].selected == true) {
           return;
      }

      var option = self.item($option);    
      var matches = self.matches(params, option);    
      if (matches !== null) {
        data.push(matches);
      }
    });

    callback({
      results: data
    });
  };
Hakan Fıstık
  • 11,376
  • 8
  • 74
  • 105
Javier
  • 21
  • 2
2

Another approach to hide the selected values, is to use the dropdown templateResult option to return null when the value is marked as selected.

function hideSelected(value) {
  if (value && !value.selected) {
    return $('<span>' + value.text + '</span>');
  }
}

$(document).ready(function() {
  $('#dynamicAttributes').select2({
    allowClear: true,
    placeholder: {
      id: "",
      placeholder: "Leave blank to ..."
    },
    minimumResultsForSearch: -1,
    width: 600,
    templateResult: hideSelected,
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2/js/select2.min.js"></script>

<select id="dynamicAttributes" multiple="true" data-tags="true">
  <option value="1">A</option>
  <option value="2">B</option>
  <option value="3">C</option>
</select>
Will B.
  • 14,243
  • 4
  • 56
  • 62
0
$(document).ready(function(){
  $('#dynamicAttributes').select2({
        allowClear: true,
        minimumResultsForSearch: -1,
        width: 600
  });
});

this make a error when click the remove sign button

TypeError: this.placeholder is undefined

use

 $(document).ready(function(){
      $('#dynamicAttributes').select2({
            allowClear: true,
            minimumResultsForSearch: -1,
            width: 600,
            placeholder: 'past your placeholder'

      });
});
Tabish Usman
  • 2,810
  • 2
  • 15
  • 15
0

Remove (UnSelect) item from select2 multiple selected items

first step: add 'multiple' css class to your select2 element to get the true element which you want

<select class="multiple">
....
</select>

    $('select.multiple').on('select2:selecting', function (e) {
        var select = this;
        var idToRemove = '0';
        var selections = $(select).select2('data');

        var Values = new Array();

        for (var i = 0; i < selections.length; i++) {
            if (idToRemove !== selections[i].id) {
                Values.push(selections[i].id);
            }
        }
        $(select).val(Values).trigger('change');
    });
0

If you have change trigger or unselect click use this:

$("#dynamicAttributes").val(null).trigger("change");

else

$("#dynamicAttributes").val('')

If you want to completely empty the list use

$("#dynamicAttributes").empty()

Happy coding

buddemat
  • 1,992
  • 6
  • 9
  • 23
-6
$("#cqte").select2("val", "");
//cqte is id of dropdown 
Zoe
  • 23,712
  • 16
  • 99
  • 132