How do I display the selected tags in Select2 below the dropdown box?

Mhluzi Bhaka picture Mhluzi Bhaka · May 22, 2015 · Viewed 12.5k times · Source

I am using Select2 (version 4) with tags and would like to have the selected choices display below the input field.

So instead of:

Standard choices

Rather have:

enter image description here

Is this possible and if so how do I achieve that?

EDIT: Code is:

<select class="js-example-tags form-control" multiple="multiple">
    <option selected="selected">orange</option>
    <option selected="selected">white</option>
    <option selected="selected">purple</option>
    <option selected="selected">red</option>
    <option selected="selected">blue</option>
    <option selected="selected">green</option>
</select>

and

$(".js-example-tags").select2({
tags: true
})

Answer

TJ Nicolaides picture TJ Nicolaides · Dec 7, 2015

I came across this question a few weeks ago and wanted to share an alternative solution that I felt carried less risk than some of the style modifications to Select2 that other answers required.

What our team ended up using was a script that listened to the change event of the underlying <select> element to build/rebuild a styled unordered list in a sibling element:

$(".js-example-tags").select2({
    tags: true
}).on('change', function() {
    var $selected = $(this).find('option:selected');
    var $container = $(this).siblings('.js-example-tags-container');

    var $list = $('<ul>');
    $selected.each(function(k, v) {
       var $li = $('<li class="tag-selected"><a class="destroy-tag-selected">×</a>' + $(v).text() + '</li>');
       $list.append($li);
    });
    $container.html('').append($list);
}).trigger('change');

And, to give the new list the functionality in addition to the appearance of the select2 tags, we listened for a click event and paired each list item with the corresponding option in the <select> so it could toggle the selected state and trigger the change event again:

$selected.each(function(k, v) {
    var $li = $('<li class="tag-selected"><a class="destroy-tag-selected">×</a>' + $(v).text() + '</li>');
    $li.children('a.destroy-tag-selected')
        .off('click.select2-copy')
        .on('click.select2-copy', function(e) {
              var $opt = $(this).data('select2-opt');
              $opt.attr('selected', false);
              $opt.parents('select').trigger('change');
        }).data('select2-opt', $(v));
    $list.append($li);
});

After this, it was a matter of using display: none to hide the .select2-selection__choice elements.

Note in jQuery version > 3 set property instead of attribute $opt.prop('selected', false) in other case it will not remove created tags;

The full example is available for review here: http://jsfiddle.net/tjnicolaides/ybneqdqa/ -- hope this helps someone else.