'Select2: Hide certain optgroup dynamically

I need to hide/show a certain option group (<optgroup>) conditionally and I've tried the top solution from this question - Select2: Hide certain options dynamically

It hides every option (as required), but group title stays visible, although it has no child items. How to hide the whole option group in select2?



Solution 1:[1]

I think you can disable <optgroup> in Select2 only using data array source, not using options in HTML.

See issues on Select2 github repo:

Here is a snippet which exemplifies the two approach:

var data = [{
  text: 'group1',
  children: [{
    id: '1',
    text: 'option 1'
  }, {
    id: '2',
    text: 'option 2',
    disabled: false,
  }, {
    id: '3',
    text: 'option 3',
    disabled: true,
  }]
},
{
  text: 'group2',
  disabled: true,
  children: [{
    id: '4',
    text: 'option 4',
    disabled: true,
  }, {
    id: '5',
    text: 'option 5'
  }]
}];

$(document).ready(function() {
  $('#test').select2({  data: data, });
  $('#test2').select2();
});

var group2Disabled = true;

toggleGroup2 = function() {
	group2Disabled = !group2Disabled;
  console.log("toggleGroup2", group2Disabled);
  var gr2 = data.find(findGroup2);
  gr2.disabled = !gr2.disabled;
  $('#test').empty().select2({data:data}).trigger("change");
}

function findGroup2(el) { 
    return el.text === 'group2';
}
select {
  width: 40%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>

<label>Select List #1 (data)</label>
<select id="test"></select>
<button onclick="toggleGroup2()">toggle disable Group2</button>

<br><br><br>

<label>Select List #2 (html)</label>
<select id="test2">
  <optgroup label="group1">
    <option>option 1</option>
    <option>option 2</option>
    <option disabled="true">option 3</option>
  </optgroup>
  <optgroup label="group2" disabled="true">
    <option disabled="true">option 4</option>
    <option>option 5</option>
  </optgroup>
</select>

Or you can check this jsfiddle: https://jsfiddle.net/beaver71/u0jekg44/

Solution 2:[2]

You can use this .css to hide the options and the optgoup

.select2-results__option[aria-disabled=true]
{
    display: none;
}

Don't forget to put the disabled="true" attribute in both elements. You can also set this attribute dynamically using JQuery ($(theOption).prop('disabled', true)).

Solution 3:[3]

for whoever stumbles upon this, no, you do n?t need to alter the data source in order to disable an opt group

like Mateus wrote, css to hide disabled options and optgroups:

.select2-results__option[aria-disabled=true]
{
    display: none;
}

and javascript logic to disable optgroups, if they have no options enabled:

mySelect.find("optgroup").each(function(){
    let totalOptions = $(this).find("option").length
    let disabledOptions = $(this).find("option:disabled").length

    if( totalOptions == disabledOptions ) $(this).prop('disabled', true)
    else $(this).prop('disabled', false)
})

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 beaver
Solution 2 Mateus Barros Pinheiro
Solution 3 Manos