How to use different colors for each select2 option?
Asked Answered
C

4

13

I'm using a select2 dropdown, and would like to set different colours on each options.

Example:

<select class="select2" name="fruit">
  <option class="red-option">Apple</option>
  <option class="green-option">Kiwi</option>
  <option class="blue-option">Grape</option>
</select>

I can colourize the rendered, selected option as follow:

.select2-selection__rendered[title="Apple"] {
  color: red !important;
}

How to also colourize the options in the select2 dropdown - either based on the option class ('red-option') or value ('Apple')?

PS: I use bootstrap 3.3 + jQuery and don't mind using JS to do this if I must.

Crural answered 12/4, 2018 at 16:25 Comment(0)
C
4

Got it.

Select2 generates an id attribute for all the dropdown options, using the parent select's name attribute.

With my example, I was able to apply a colour using :nth-child(x) as follow:

.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(1) {
  color: red;
}
.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(2) {
  color: green;
}
.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(3) {
  color: blue;
}
<select class="select2" name="fruit">
    <option class="red-option">Apple</option>
    <option class="green-option">Kiwi</option> 
    <option class="blue-option">Grape</option> 
</select>
Crural answered 16/4, 2018 at 14:19 Comment(1)
sorry, but I don't find this answer as the correct one: what is the point having different classes to to the options if you use nth-child??? and in this way, if the options are not ordered you will still not achieve your goalOdlo
A
15

I found a better solution using the options

function formatState(state) {
  const option = $(state.element);
  const color = option.data("color");

  if (!color) {
    return state.text;
  }

  return $(`<span style="color: ${color}">${state.text}</span>`);
};

jQuery(node).select2({
  templateResult: formatState,
  templateSelection: formatState,
});

The color comes from the html data attribute in my case

<option style="color: #F00" data-color="#F00" value="1">Red Option</option>
Alten answered 4/10, 2020 at 12:35 Comment(4)
Thanks. This worked beautifully for styling individual options where class="red" didn't work.Plump
I have one small request. I have tried using the same code and it works fine, the only problems is it just colors the text I need the whole background for that particular item to change its color. background-color style attribute only works for that text background. I have tried using status.text.select2.parent.addClass() to get the <li> item to change its background color but it doesn't work. Can anyone please help.Melanesian
I used option.addClass("someclass") which actually worked but it still doesn't completely color the <li> element and also when I select the color option it doesn't show in the select control as selected instead it shows blank. option.parent().addClass() doesn't work either. Styling is not my strong ability, and programming after a 5 year gap so kindly please help me out.Melanesian
Thanks man with this solution I can now add html to option witch is not possible to do in a normal option ! very useful answer !Footstalk
C
4

Got it.

Select2 generates an id attribute for all the dropdown options, using the parent select's name attribute.

With my example, I was able to apply a colour using :nth-child(x) as follow:

.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(1) {
  color: red;
}
.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(2) {
  color: green;
}
.select2-results__options[id*="select2-fruits"] .select2-results__option:nth-child(3) {
  color: blue;
}
<select class="select2" name="fruit">
    <option class="red-option">Apple</option>
    <option class="green-option">Kiwi</option> 
    <option class="blue-option">Grape</option> 
</select>
Crural answered 16/4, 2018 at 14:19 Comment(1)
sorry, but I don't find this answer as the correct one: what is the point having different classes to to the options if you use nth-child??? and in this way, if the options are not ordered you will still not achieve your goalOdlo
B
2

You can use the CSS attribute selector like so on select2-results__option elements:

$(".select2").select2();
.select2-selection__rendered[title="Apple"] {
  color: red !important;
}

.select2-results__option[id*="Apple"] {
  color: red;
}

select {
  width: 200px;
}
<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.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>

<select class="select2" name="fruit">
  <option class="red-option">Apple</option>
  <option class="green-option">Kiwi</option>
  <option class="blue-option">Grape</option>
</select>
Builtin answered 12/4, 2018 at 19:13 Comment(1)
That doesn't seem to work. The id attribute give to the results options are using the select's name attribute, instead of the options attribute. In my example, the id that select2 applies to .select2-results__option is something like select2-fruits-a0-result-rh69-1Crural
S
0

Here is a very simple and generic approach to adding a class to select2 options:

$('.select2').select2({
    // render html in the dropdown
    templateResult: function(el) { return '<span class="' + ($(el.element).prop('class') || '') + '">' + el.text + '</span>'; },
    // render html for the selected option
    templateSelection: function(el) { return '<span class="' + ($(el.element).prop('class') || '') + '">' + el.text + '</span>'; },
    // render html as-is without escaping it
    escapeMarkup: function(markup) { return markup; }
});

This way the select2 options will inherit any class you add to your options.

Stagey answered 20/4, 2022 at 13:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.