Set the Background Color onChange

Hi there

We use the class Select2 for several control’s in a form. Now we want to change the background color of a specific select, depending on the selected entry.
When nothing is selected, the control should have a red color to show, that this select needs to be choosen. And if the user has selected an entry, the color should be change to white.

Is that possible - and how - with Select2?

Thanks for your help

The DOM structure of the Select2 widget is not “officially” documented, but you can easily inspect it with your browser’s Inspect command. I believe you want to colorize the following element: <span class="select2-selection select2-selection--single" role="combobox" aria-haspopup="true" aria-expanded="false" tabindex="0" aria-disabled="false" aria-labelledby="select2-nd3r-container" style=" background-color: red; ">

To know when a selection has been made (or cleared, if you allow that), listen for the select2:select and select2:clear events. You can set the event listeners on your individual <select> elements, or you can set a single event listener on a common ancestor that will handle all of the events from all of your Select2’s. These events contain a params field, which contains a data field, and that field contains an element property, which is a reference to the underlying HTML <select> for the Select2 that triggered the event. In the DOM, the Select2 for each <select> is rendered immediately after that <select> (in other words, the Select2 widget is the nextElementSibling of the <select>. You can use this information to target the <span> shown above for the Select2 that triggered the event and change its background color, either by adding/removing a class, or managing the background color via the <span>'s style attribute.

Here’s an example of the event.params object:

{
  "originalEvent":"[$.Event]",
  "data": {
    "selected":true,
    "disabled":false,
    "text":"California",
    "id":"CA",
    "title":"",
    "_resultId":"select2-7fje-result-j3q8-CA",
    "element":"[DOM node]"
  },
  "_type":"select"
}

For instance, a listener like this should do what you want:

function colorizeSelect2(event) {
  const targetSelect = event.params.data.element;
  const targetSelect2 = targetSelect.nextElementSibling;
  targetSelect2.querySelector('span.select2-selection').style.backgroundColor = 
    event.type === 'select2:select' ? "#fff" : "#f00";
}

If you set this function as the event handler for select2:select and select2:clear events (you could even set it on the <body> or some other common ancestor element of all the Select2’s), it should correctly identify and colorize just the Select2 where the selection was made.

Good luck, and I hope this helps.

Hello, I hope someone can help me here.

I have a page where 6 select2 lists are rendered. Based on selections from various lists, the selection content in other lists change. This works. I sometimes need to change the color of the dropdowns that indicate “required”.

In typical (non select2) situations, you can reference the object name and flip the color. If I set the color before select 2 initialization, it retains the color as needed.

I cannot get to the objects after select2 is initialized. I’ve read that the DOM is different after initialization.

I’ve looked into this, and cannot figure out how to accomplish it.

One thing I haven’t tried is to apply a unique class to each dropdown and modify it.

Any help greatly appreciated!

Hello, I hope you might have some input here…

I have a page where 6 select2 lists are rendered. Based on selections from various lists, the selection content in other lists change. This works. I sometimes need to change the color of the dropdowns that indicate “required”.

In typical (non select2) situations, you can reference the object name and flip the color. If I set the color before select 2 initialization, it retains the color as needed.

I cannot get to the objects after select2 is initialized. I’ve read that the DOM is different after initialization.

I’ve looked into this, and cannot figure out how to accomplish it.

One thing I haven’t tried is to apply a unique class to each dropdown and modify it.

Any help greatly appreciated!