Select2 v4.0 使 optgroups 可选

Posted

技术标签:

【中文标题】Select2 v4.0 使 optgroups 可选【英文标题】:Select2 v4.0 make optgroups selectable 【发布时间】:2015-08-05 00:08:14 【问题描述】:

我正在使用最新版本的 select2 (4.0.0),但找不到使 optgroup 可选的选项。

一个 optgroup 用于对下拉列表的不同选项进行分组,如它们的基本示例所示:

我也需要这个 optgoup 是可选的!这在 3.5.1 中是可能的,但它不再是 4.0.0 中的默认设置。

我的代码如下所示:

$(document).ready(function() 
   $('#countrySelect').select2(
     data: [
       text: "group",
       "id": 1,
       children: [
         "text": "Test 2",
         "id": "2"
       , 
         "text": "Test 3",
         "id": "3",
         "selected": true
       ]
     ]
   );
 );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />


<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>

【问题讨论】:

Selectable optgroups in Select2的可能重复 不是我重复的,因为我的问题使用 select2 4.0 版,而标记的问题使用的是以前的版本。那里发布的解决方案对我不起作用。 即使它有效,我更喜欢这个答案。它解释了为什么无法选择 optgroups 可选并且不提供“hack”解决方法。 好吧,我遇到了这个问题,我找到了这个解决方法enter link description here 【参考方案1】:

这是requested over on GitHub,但实际上是it is not actually possible。以前可以使用&lt;input /&gt;,但切换到&lt;select&gt; 意味着我们现在可以使用explicitly disallow a selectable &lt;optgroup&gt;


这里有一个 Select2 可能永远无法解决的技术障碍:标准的&lt;optgroup&gt; 在浏览器中是不可选择的。并且因为带有children 的数据对象被转换为带有一组嵌套&lt;option&gt; 元素的&lt;optgroup&gt;,所以该问题适用于您遇到相同问题的情况。

最好的解决方案是have an &lt;option&gt; for selecting the group,就像使用标准选择一样。如果没有&lt;option&gt; 标记,则无法将所选值设置为组(因为该值实际上并不存在)。 Select2 甚至有一个templateResult 选项(3.x 中的formatResult),因此您可以将其作为一个组在浏览器中保持一致。

【讨论】:

:( 我的研究显示相同。因此,如果我想拥有这样的层次结构选项,我必须使用 3.5.2 或通过模板对其进行样式设置,也许可以自己查询以显示该组...您是否碰巧知道任何支持这种嵌套选择的插件。Select2 是提供此功能的最流行的插件吗?【参考方案2】:

我设法通过使用 templateResult 属性并以这种方式将点击事件附加到 optgroups 来实现这一点:

$('#my-select').select2(
    templateResult: function(item) 
    if(typeof item.children != 'undefined') 

        var s = $(item.element).find('option').length - $(item.element).find('option:selected').length;
        // My optgroup element
        var el = $('<span class="my_select2_optgroup'+(s ? '' : ' my_select2_optgroup_selected')+'">'+item.text+'</span>');

        // Click event
        el.click(function() 
        // Select all optgroup child if there aren't, else deselect all
        $('#my-select').find('optgroup[label="' + $(this).text() + '"] option').prop(
            'selected',
            $(item.element).find('option').length - $(item.element).find('option:selected').length
        );
        // Trigger change event + close dropdown
        $('#my-select').change();
        $('#my-select').select2('close');
        );

        // Hover events to properly manage display 
        el.mouseover(function() 
        $('li.select2-results__option--highlighted').removeClass('select2-results__option--highlighted');
        );
        el.hover(function() 
        el.addClass('my_select2_optgroup_hovered');
        , function() 
        el.removeClass('my_select2_optgroup_hovered');
        );
        return el;
    
    return item.text;
    
);

以及相关的css:

.my_select2_optgroup_selected 
    background-color: #ddd;

.my_select2_optgroup_hovered 
    color: #FFF;
    background-color: #5897fb !important;
    cursor: pointer;

strong.select2-results__group 
    padding: 0 !important;

.my_select2_optgroup 
    display: block;
    padding: 6px;

【讨论】:

这应该是公认的答案,小姐,谢谢!【参考方案3】:

好吧,我遇到了这个问题,我发现每次打开 select2 (Select2 4.0.5) 时,它都会在关闭 body 元素之前添加一个 span 元素。此外,在 span 元素内部添加了一个 ul,其 id 为:select2-X-results,其中 X 是 select2 id。 所以我找到了以下解决方法(jsfiddle):

var countries = [
  "id": 1,
  "text": "Greece",
  "children": [
    "id": "Athens",
    "text": "Athens"
  , 
    "id": "Thessalonica",
    "text": "Thessalonica"
  ]
, 
  "id": 2,
  "text": "Italy",
  "children": [
    "id": "Milan",
    "text": "Milan"
  , 
    "id": "Rome",
    "text": "Rome"
  ]
];

$('#selectcountry').select2(
  placeholder: "Please select cities",
  allowClear: true,
  width: '100%',
  data: countries
);

$('#selectcountry').on('select2:open', function(e) 

  $('#select2-selectcountry-results').on('click', function(event) 

    event.stopPropagation();
    var data = $(event.target).html();
    var selectedOptionGroup = data.toString().trim();

    var groupchildren = [];

    for (var i = 0; i < countries.length; i++) 


      if (selectedOptionGroup.toString() === countries[i].text.toString()) 

        for (var j = 0; j < countries[i].children.length; j++) 

          groupchildren.push(countries[i].children[j].id);

        

      


    


    var options = [];

    options = $('#selectcountry').val();

    if (options === null || options === '') 

      options = [];

    

    for (var i = 0; i < groupchildren.length; i++) 

      var count = 0;

      for (var j = 0; j < options.length; j++) 

        if (options[j].toString() === groupchildren[i].toString()) 

          count++;
          break;

        

      

      if (count === 0) 
        options.push(groupchildren[i].toString());
      
    

    $('#selectcountry').val(options);
    $('#selectcountry').trigger('change'); // Notify any JS components that the value changed
    $('#selectcountry').select2('close');    

  );
);
li.select2-results__option strong.select2-results__group:hover 
  background-color: #ddd;
  cursor: pointer;
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.full.min.js"></script>


<h1>Selectable optgroup using select2</h1>
<select id="selectcountry" name="country[]" class="form-control" multiple style="width: 100%"></select>

【讨论】:

【参考方案4】:

今天遇到了同样的问题。这当然不是我最好的解决方案,但乞丐不能选择:

$(document).on('click', '.select2-results__group', function(event) 
        let select2El = $('#mySelect2');
        var setValues = [];
        //Add existing Selection
        var selectedValues = select2El.select2('data');
        for ( var i = 0, l = selectedValues.length; i < l; i++ ) 
            setValues.push(selectedValues[i].id);

        
        //Add Group Selection
        $(this).next('ul').find('li').each(function()
            let pieces = $(this).attr('data-select2-id').split('-');
            setValues.push(pieces[pieces.length-1]);
        );
        select2El.val(setValues).trigger('change').select2("close");
    );

【讨论】:

【参考方案5】:

$(document).ready(function() 
   $('#countrySelect').select2(
     data: [
       text: "group",
       "id": 1,
       children: [
         "text": "Test 2",
         "id": "2"
       , 
         "text": "Test 3",
         "id": "3",
         "selected": true
       ]
     ]
   );
 );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://select2.github.io/dist/js/select2.full.js"></script>
<link href="https://select2.github.io/dist/css/select2.min.css" rel="stylesheet" />


<select id="countrySelect" style="width: 380px;" placeholder="Select regions..."></select>

【讨论】:

以上是关于Select2 v4.0 使 optgroups 可选的主要内容,如果未能解决你的问题,请参考以下文章

Select2:动态隐藏某些 optgroup

使用 select2 折叠/展开 optgroup

使用 select2 显示匹配 optgroup 的结果

使用 select2 的可选 optgroup

Select2 中的可选 optgroup

在 Select2 中动态添加选项和 optgroup