Sireini
Sireini

Reputation: 4262

jQuery Select2 issue with shown selection

I am working on a select menu where I use Select-2 plugin to customize it as I would like to. Thereby I have an issue I try to recreate the selected items in the input field. So when you select an item it appear as small grey list item in the input field.

Here is a FIDDLE which shows the issue I have.

There by this is the javascript code how I render my input field:

var selectMenuItems = [
        {id: 'restaurant', value: 'restaurant'},
        {id: 'shopping', value: 'shopping'},
        {id: 'toilet', value: 'toilet'}
    ]

     function formatSelectItem (selectItem) {
        if (!selectItem.id) { return selectItem.value; }
        var $selectItem = $(
        '<img src="img/markers/'+ selectItem.id.toLowerCase() +'.png"/>' +
        '<span class="select-item-text">'+ selectItem.value+"</span>"
        );
        return $selectItem;
    };

    $("[name='select']").select2({
        placeholder: "Selecteer een categorie",
        templateResult: formatSelectItem,
        data: selectMenuItems
    }).on("change", function(e){
        console.log(e);

        $('.select-multiple :selected').each(function(i, selected) {
            var selectedValue = $(selected).val();

            $('.select2-selection__choice').text(selectedValue);
        });
    });

The problem is that when I select an item it appears with text inside the input field but if I select multiple all the items will change to that last selected item text. How can I only bind this .text() to that specific select item?

In the documentation of the plugin Select-2 plugin there is an example of called "Templating" where they don't have to appent the text or image to the selected item..

Upvotes: 4

Views: 2129

Answers (4)

Mihai Alexandru-Ionut
Mihai Alexandru-Ionut

Reputation: 48367

Here is the shortest method:

$('.select-multiple :selected').each(function(i, selected) {
   $('.select2-selection__choice').eq(i).text($(this).val());
});

If you want to include images in options selected , use templateSelection function.You can override the display of the selection by setting the templateSelection option to a JavaScript function.

(function($) {
        $(function() {
            var selectMenuItems = [
               {id: 'restaurant', text: 'restaurant', img: 'http://www.freeiconspng.com/uploads/restaurant-icon-png-7.png'},
               {id: 'shopping', text: 'shopping', img: 'http://www.pngall.com/wp-content/uploads/2016/04/Shopping-Free-PNG-Image.png'},
               {id: 'toilet', text: 'toilet', img: 'http://www.freeiconspng.com/uploads/toilet-icon-png-32.png'}
            ]

            function formatSelectItem (selectItem) {
                if (!selectItem.id) { return selectItem.text; }
                var $selectItem = $(
                    '<img src="'+ selectItem.img +'" width="50px" height="50px"/>' +
                    '<span class="select-item-text">'+ selectItem.text+"</span>"
                );
               return $selectItem;
            };
            function formatState (opt) {
                if (!opt.id) {
                   return opt.text;
                }                               
                var $opt = $(
                  '<span><img src="'+opt.img +'" width="50px" height="50px"/>' + opt.text + '</span>'
                );
                return $opt;
            };
            $("[name='select']").select2({
               placeholder: "Selecteer een categorie",
               templateResult: formatSelectItem,
               templateSelection: formatState,
               data: selectMenuItems
            });
            
        });
})(jQuery);            
.flag-text { margin-left: 10px; }

.select2 {
  width: 100% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<select id="type" name="select" class="select-multiple" multiple="multiple" data-role="none"></select>

Upvotes: 1

Zakaria Acharki
Zakaria Acharki

Reputation: 67505

Working fiddle.

What you looking for is every time to loop through the selcted values provided by $(this).val() and append the value to the .select2-selection__choice by index using .eq() :

$("[name='select']").select2({
  placeholder: "Selecteer een categorie",
  templateResult: formatSelectItem,
  data: selectMenuItems
}).on("change", function(e){
  $.each($(this).val(), function(i, selected) {
    $('.select2-selection__choice').eq(i).prepend(selected+' ');
  });
});

NOTE : Use prepend() instead of tex() to preserve the 'X' in the tag.

Hope this helps.

(function($) {
  $(function() {
    var selectMenuItems = [
      {id: 'restaurant', value: 'restaurant'},
      {id: 'shopping', value: 'shopping'},
      {id: 'toilet', value: 'toilet'}
    ]

    function formatSelectItem (selectItem) {
      if (!selectItem.id) { return selectItem.value; }
      var $selectItem = $(
        '<img src="img/markers/'+ selectItem.id.toLowerCase() +'.png"/>' +
        '<span class="select-item-text">'+ selectItem.value+"</span>"
      );
      return $selectItem;
    };

    $("[name='select']").select2({
      placeholder: "Selecteer een categorie",
      templateResult: formatSelectItem,
      data: selectMenuItems
    }).on("change", function(e){
      $.each($(this).val(), function(i, selected) {
        $('.select2-selection__choice').eq(i).prepend(selected+' ');
      });
    });

  });
})(jQuery);            
.flag-text { margin-left: 10px; }

.select2 {
  width: 100% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<select id="type" name="select" class="select-multiple" multiple="multiple" data-role="none"></select>

Snippet using pictures :

(function($) {
  $(function() {
    var selectMenuItems = [
      {id: 'restaurant', value: 'restaurant', img: 'https://www.hughesinsurance.co.uk/img/front/map-marker.png'},
      {id: 'shopping', value: 'shopping', img: 'http://king-of-truck.byclickeat.fr/media/cache/square_40/front/bundle/clickeat/img/map-marker.png'},
      {id: 'toilet', value: 'toilet', img: 'http://www.onebabyowner.co.uk/sites/all/themes/onebabyowner/img/icon/map-marker.png'}
    ]

    function formatSelectItem (selectItem) {
      if (!selectItem.id) { return selectItem.value; }
      var $selectItem = $(
        '<img src="'+ selectItem.img +'"/>' +
        '<span class="select-item-text">'+ selectItem.value+"</span>"
      );
      return $selectItem;
    };

    $("[name='select']").select2({
      placeholder: "Selecteer een categorie",
      templateResult: formatSelectItem,
      data: selectMenuItems
    }).on("change", function(e){
      $.each($(this).val(), function(i, selected) {
        $('.select2-selection__choice').eq(i).prepend(selected+' ');
      });
    });

  });
})(jQuery);            
.flag-text { margin-left: 10px; }

.select2 {
  width: 100% !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
<select id="type" name="select" class="select-multiple" multiple="multiple" data-role="none"></select>

Upvotes: 2

Sireini
Sireini

Reputation: 4262

I thought I had to do this with jquery but when I changed the Array of selectMenuItems value to text the plugin does the work for me:

 var selectMenuItems = [
   {id: 'restaurant', text: 'restaurant'},
   {id: 'shopping', text: 'shopping'},
   {id: 'toilet', text: 'toilet'}
 ]

Just a simple fix where I thought I could set any property there

Upvotes: 0

Mark Schultheiss
Mark Schultheiss

Reputation: 34178

In your code

        $('.select-multiple :selected').each(function(i, selected) {
            var selectedValue = $(selected).val();

            $('.select2-selection__choice').text(selectedValue);
        });

You need to split the selectedValue into the values and search each of those to put in the text appropriate for that index of values.

In other words, replace that code as such:

     $('.select-multiple :selected').each(function(i, selected) {
        var selectedValue = $(this).val();
        $('.select2-selection__choice').eq(i).text(selectedValue);
      });

Upvotes: 0

Related Questions