How to add class to select2 element in v4.0
Asked Answered
R

5

31

This is very similar to this question on how to add class to select2 element, however the answers there appear to target earlier versions of the framework which has undergone some breaking changes in v4.0

According to this issue to add an additional custom class to select2-container, there were several undocumented properties you could pass to the select2 constructor, including: containerCss, containerCssClass, dropdownCss, and dropdownCssClass.

However in version 4 when I run the following code:

$('.select2').select2({
    containerCss: "wrap"
});

I get the following error:

Uncaught Error: No select2/compat/containerCss

How can I pass a class to Select2 in v4.0?

Here's an example in StackSnippets:

$('.select2').select2({
    containerCss: "wrap"
});
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select class="select2 narrow wrap">
  <option value="AL">Algebra</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Rift answered 11/6, 2015 at 18:55 Comment(0)
C
41

Select2 will store all the information it uses on the original select element. You can access the following information by calling .data('select2') on the original element:

Select2 Data

From there, you can access the $container property to identify the container in the DOM and add the class to that like this:

var $select2 = $('select.select2').select2()

$select2.data().select2.$container.addClass("wrap")

Here's a demo in Stack Snippets

var $select2 = $('select.select2').select2()
$select2.data().select2.$container.addClass("wrap")
body .select2.narrow {
    width: 200px;
}
body .wrap .select2-selection--single {
    height: 100%;
}
body .select2-container.wrap .select2-selection--single .select2-selection__rendered {
    word-wrap: break-word;
    text-overflow: inherit;
    white-space: normal;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.full.js"></script>

<select class="select2 narrow wrap">
  <option value="AL">Really long name that normally</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Cyanate answered 21/9, 2015 at 10:23 Comment(4)
Welcome to SO! Please always provide an explanation to your answers. Often answers without explanations are hard understand, or the point you're trying to make is not apparent. In this particular case I also wonder about the added value of this answer compared to what's already there...Abreaction
@nulle, I've updated the answer to include a demo, but cfi is quite correct. I think there is a value add to your answer, but it came close to deletion without providing an explanation as to what you were doing. Hint: if there's already a working stack snippet in the answer, you can just click copy to answer and tweak the part of the code you're updating. Even that's not a substitute for an explanation, but it is a helpful POC and forces you to flesh out missing parts of the answer like .addClassRift
@Rift Using JQuery if you can get a hold of the <option> object with $('#my_id').select2(); is there a way to use JQuery to grab to the corresponding <li> that Select2 is displaying for that <option> tag? I'd like to hide all the drop-down options that have a certain class. Thanks for any help!Legionary
For those of you looking to target the dropdown list (which is appended to <body>) you can access it in a similar fashion: $('#select2').select2().data('select2').$dropdown.addClass("wrap");Savoie
R
20

You can use the following options to add a class to the container (selection) or dropdown (options):

$('.select2').select2({
    containerCssClass: "custom-container",
    dropdownCssClass: "custom-dropdown",
});

According to the Migration Guide in the 4.0 Announcement:

If you use the full build of Select2 (select2.full.js) compatibility modules will be used in some cases to ensure that your code still behaves how you were expecting.

According to the Configuration Docs, the following options can be passed:

Configuration Docs

However, Select2 isn't great about defining what a "container" is and where you'd expect to find it.

Here's a breakdown of some of high level html structures and where the custom classes show up:

Select2 Container vs Dropdown

Here's a running demo that outputs the custom classes to the container and dropdown wrappers and then uses them to style the color of each section (just to prove they're being inserted)

$('.select2').select2({
    containerCssClass: "custom-container",
    dropdownCssClass: "custom-dropdown",
});
select {
  width: 200px;
}

.custom-container span {
  color: blue!important;
}
.custom-dropdown {
  color: red;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.full.js"></script>

<select class="select2">
  <option value="AL">Algebra</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Rift answered 11/6, 2015 at 19:16 Comment(5)
I've upvoted the comment made by @walther but just after that I discovered that I've been not including select2.full.js version - containerCssClass is not available only in the basic module.Soule
That only applies it to the select2-selection. What about the actual dropdown itself? select2-containerTractate
This option is not working, I have tried and it nothing class added into container class. I guess select2 itself bug?Maddock
@Codemole, I added some further explanation. It should be working, but it might not be clear how it's working, so hopefully that helpsRift
containerCssClass has been renamed to selectionCssClass in v4.Dinin
U
2

Found a way to add a class. had the same problem couldnt find a way and made it myself, so here it is:

$('.select2').on('click',function(){
  var matchBlock = $(this).prev();
  if(matchBlock.hasClass('select-control-left')){
    $('.select2-dropdown').addClass('blue-select');
  }
  else{
     $('.select2-dropdown').addClass('orange-select');
  }
});
Ursala answered 23/8, 2015 at 21:44 Comment(0)
F
1

We're using a React wrapper for Select2, so none of the current answers worked for us. However, we were able to make CSS that targeted the container even though we could not add a class to it by adding the class to the base element, then using an adjacent CSS selector:

$('.select2').select2();
.wrap + .select2-container .select2-selection--single {
    border: solid 1px #F00;
}
<link href="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.js"></script>

<select class="select2 narrow wrap">
  <option value="AL">Algebra</option>
  <option value="AK">Alaska</option>
  <option value="AZ">Arizona</option>
</select>
Frasco answered 29/3, 2016 at 22:27 Comment(0)
P
0

Here is the short answer if you want to add class to all elements.

$.fn.select2.defaults.set('containerCssClass', 'wrap');
Puerperium answered 8/7, 2016 at 13:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.