34
votes

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/

8

8 Answers

87
votes

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

3
votes

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.

2
votes

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
    });
  };
2
votes

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>
0
votes
$(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'

      });
});
0
votes

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
votes

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

-6
votes
$("#cqte").select2("val", "");
//cqte is id of dropdown