Search code examples
jquery-select2jquery-select2-4

Preserve option class in jquery select2 dropdown items


Does anybody know if it possible to transfer the element class to the jquery select2 dropdown items?

<select>
  <option class="group-1"></option>
  <option class="group-1"></option>
  <option class="group-2"></option>
  <option class="group-2"></option>
</select>

I am trying to build a dynamic list based on a user's selected value from another dropdown, so if a user selects 'group 1' then I wish to only show the items with class 'group-1'. I was hoping to be able to do something like $('ul.select2 li.group-2').hide().

EDIT: I am splitting this question into 2 for clarity in the answers I have developed to solve this problem,

  1. How to preserve option element classes in the select2 listing? - I am providing an answer below for those interested in this.
  2. How to dynamically filter a select2 listing based on option class? I have opened a new question thread in which I am answering this question as the solutions quite different.

Solution

  • I managed to solve the question by using the templating functionality of the select2 plugin,

    <script type="text/javascript">
    (function( $ ) {
      'use strict';
    
      var opportunities = $('select#opportunities').select2({
        dropdownParent: $('#select-opportunity'),
        templateResult: formatItem
      });
      function formatItem (state) {
        if (!state.id) { return state.text; }
        var $state = $(
          '<span class="opportunity-item ' + state.element.className + '">' + state.text + '</span>'
        );
        return $state;
      }
    })( jQuery );
    </script>
    

    NOTE: this does not allow you to manipulate the select2 dropdown list because the class attribute is only transfered to the inner custom <span> element of our item, and not to the actual <li> element of the dropdown select2 list. However it becomes very useful to further style the dropdown list, for example,

    <style>
    .opportunity-item.group-1::after{
      content: '';
       display: inline-block;
       margin-left:5px;
       width: 10px;
       height: 10px;
       -moz-border-radius: 10px;
       -webkit-border-radius: 10px;
       border-radius: 10px;
       background-color: green;
    }
    .opportunity-item.group-2::after{
      content: '';
       display: inline-block;
       margin-left:5px;
       width: 10px;
       height: 10px;
       -moz-border-radius: 10px;
       -webkit-border-radius: 10px;
       border-radius: 10px;
       background-color: blue;
    }
    </style>
    

    resulting in,

    which makes for a nice visual distinction between different groups