html 使用select2可选择的optgroup

j5fpnvbx  于 2023-03-27  发布在  其他
关注(0)|答案(9)|浏览(236)

我已经使用select2从下拉列表中选择多个选项,但是select2是否可以选择完整的optgroup??我想要的是当用户选择选项组时,所有的子选项都应该被选中。我想使用jQuery Select2来做到这一点。我如何做到这一点?

7gyucuyw

7gyucuyw1#

如果使用隐藏的input元素(而不是select元素)支持Select 2,这是可能的。
要使组选项可选择,您必须给予一个“id”,但它似乎可以是一个空字符串。然后您可以使用“select 2-selecting”事件来防止组选项被选择,而是选择其子选项。
另外,可以提供query函数以防止组选项在其所有子选项已经被选择之后出现在列表中。
如果你有这样定义的选项:

var FRUIT_GROUPS = [
    {
        id: '',
        text: 'Citrus',
        children: [
            { id: 'c1', text: 'Grapefruit' },
            { id: 'c2', text: 'Orange' },
            { id: 'c3', text: 'Lemon' },
            { id: 'c4', text: 'Lime' }
        ]
    },
    {
        id: '',
        text: 'Other',
        children: [
            { id: 'o1', text: 'Apple' },
            { id: 'o2', text: 'Mango' },
            { id: 'o3', text: 'Banana' }
        ]
    }
];

你可以像这样插入Select 2:

$('#fruitSelect').select2({
    multiple: true,
    placeholder: "Select fruits...",
    data: FRUIT_GROUPS,
    query: function(options) {
        var selectedIds = options.element.select2('val');
        var selectableGroups = $.map(this.data, function(group) {
            var areChildrenAllSelected = true;
            $.each(group.children, function(i, child) {
                if (selectedIds.indexOf(child.id) < 0) {
                    areChildrenAllSelected = false;
                    return false; // Short-circuit $.each()
                }
            });
            return !areChildrenAllSelected ? group : null;
        });
        options.callback({ results: selectableGroups });
    }
}).on('select2-selecting', function(e) {
    var $select = $(this);
    if (e.val == '') { // Assume only groups have an empty id
        e.preventDefault();
        $select.select2('data', $select.select2('data').concat(e.choice.children));
        $select.select2('close');
    }
});

jsfiddle
下面是一个没有query函数的jsfiddle,当所有子选项都被选中时,组选项仍然显示。

oknwwptz

oknwwptz2#

我发现Select 2 v4的一个插件,它增加了点击optgroup来选择/取消选择所有子选项的功能。它对我来说非常有效。bnjmnhndrsn/select2-optgroup-select
谢谢本·亨德森!

332nm8kg

332nm8kg3#

我使用过John的代码,但我的问题是我需要过滤的能力,所以我添加了它。
这是查询代码:

query: function (options) {
            var selectedIds = options.element.select2('val');
            var data = jQuery.extend(true, {}, FRUIT_GROUPS);
            var selectableGroups = $.map(data, function (group) {
                var areAllChildrenSelected = true,
                    parentMatchTerm = false,
                    anyChildMatchTerm = false;
                if (group.text.toLowerCase().indexOf(options.term.toLowerCase()) >= 0) {
                    parentMatchTerm = true;
                }
                var i = group.children.length
                while (i--) {
                    var child = group.children[i];

                    if (selectedIds.indexOf(child.id) < 0) {
                        areAllChildrenSelected = false;
                    };

                    if (options.term == '' || (child.text.toLowerCase().indexOf(options.term.toLowerCase()) >= 0)) {
                        anyChildMatchTerm = true;
                    }
                    else if (!parentMatchTerm) {
                        var index = group.children.indexOf(child);
                        if (index > -1) {
                            group.children.splice(index, 1);
                        };
                    };
                };

                return (!areAllChildrenSelected && (parentMatchTerm || anyChildMatchTerm)) ? group : null;
            });

            options.callback({ results: selectableGroups });
        }
cpjpxq1n

cpjpxq1n4#

首先给予id你的选择例如
<select style="width: 95%" id="selectgroup">
然后将类添加到您的optgroup,如

<optgroup value="ATZ" label="Alaskan/Hawaiian Time Zone" class="select2-result-selectable">

然后加上这个

$('#selectgroup').select2({

    }).on('select2-selecting', function (e) {
        debugger;
        var $select = $(this);
        if (e.val == undefined) {
            e.preventDefault();
            var childIds = $.map(e.choice.children, function (child) {
                return child.id;
            });
            $select.select2('val', $select.select2('val').concat(childIds));
            $select.select2('close');
       }
    });

如果你点击optgroup,它会选择optgroup下的所有选项。

o75abkj4

o75abkj45#

好吧,我遇到了这个问题,我发现每次select 2(Select 2 4.0.5)打开时,它都会在关闭body元素之前添加一个span元素。此外,在span元素内添加一个id为的ul:select 2-X-results,其中X是select 2 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>
xzv2uavs

xzv2uavs6#

V4.0.2使用select元素的一个选项是:

<select style="width:100%;" id="source" multiple="" tabindex="-1" aria-hidden="true">                 
   <optgroup class="select2-result-selectable" label="Statuses"   >        
      <option value="1">Received</option>                          
      <option value="2">Pending Acceptance</option>                             
   </optgroup>                                 
   <optgroup class="select2-result-selectable" label="Progress" >                
      <option value="6">In Progress</option>
      <option value="7">Follow Up</option>                         
  </optgroup>                                                    
</select>

JS + JQuery:

$(document).ready(function() {

   $('#source').select2();

$(document).on("click", ".select2-results__group", function(){

    var groupName = $(this).html()
    var options = $('#source option');

    $.each(options, function(key, value){

        if($(value)[0].parentElement.label.indexOf(groupName) >= 0){
            $(value).prop("selected","selected");
        }

    });

    $("#source").trigger("change");
    $("#source").select2('close'); 

  });
});

小提琴:https://jsfiddle.net/un1oL8w0/4/

zbwhf8kr

zbwhf8kr7#

在Select 2 v4中,我发现John S的答案不起作用(see here)。我使用 AJAX 将数据作为数组加载,并创建了一个解决方案:

$(document).on("click", ".select2-results__group", function(){
    var input = $(this);
    var location = input.html();
    // Find the items with this location
    var options = $('#select2 option');
    $.each(options, function(key, value){
        var name = $(value).html();
        // The option contains the location, so mark it as selected
        if(name.indexOf(location) >= 0){
            $(value).prop("selected","selected");
        }
    });
    $("#select2").trigger("change");
});

我按位置对我的项目进行分组,每个选项都在其html中的某个位置包含位置名称。每当单击optgroup标题时,我都会得到它的位置(下拉列表中显示的名称)。然后我查看#select2表中的所有选项,并找到哪些选项在其html中包含该位置。
我知道这是一个黑客的变通方法,但希望它有助于/指向正确的方向。

mnowg1ta

mnowg1ta8#

John S提供的示例在大多数情况下都能很好地工作(对于V3)。但是它有一个错误:
假设选择列表足够长,可以滚动。当您选择任何组中的任何项目时,只有在向下滚动后才可用-您不能再选择该组中所选项目之后的下一个项目。这是因为select 2的ensureHighlightVisible方法开始行为失常,因为它使用的选择器使用假设组总是“不可选”。因此,每次您尝试选择该项目时,滚动条都会跳转。
所以不幸的是,虽然这个解决方案看起来真的很好-我放弃了它,并重新实现了它,而不使用组ID:

$selectEl..on("select2-open", function(event) {
          $(event.target).data("select2").dropdown.on("click", "li.select2-result-unselectable", selectGroup);
          $(event.target).data("select2").dropdown.on("mousemove-filtered", "li.select2-result-unselectable", highlight);
        }).on("select2-close", function(event) {
          $(event.target).data("select2").dropdown.off("click", "li.select2-result-unselectable", selectGroup);
          $(event.target).data("select2").dropdown.off("mousemove-filtered", "li.select2-result-unselectable", highlight);
        });

// selection of the group.
  function selectGroup(e) {
    var $li = $(this);
    e.preventDefault();
    $select.select2('data', $select.select2('data').concat($li.data("select2Data").children));
    $select.select2('close');
    _this.$field.trigger('change');
  }

  // highlight of the group.
  function highlight(e) {
    if ($(e.target).hasClass("select2-result-unselectable") || $(e.target.parentNode).hasClass('select2-result-unselectable')) {
      e.preventDefault();
      e.stopPropagation();
      $select.data("select2").dropdown.find(".select2-highlighted").removeClass("select2-highlighted");
      $(this).addClass("select2-highlighted");
    }
  }
ifmq2ha2

ifmq2ha29#

您可以使用templateResult为组和子级添加特定行为。

const something = {
    "results": [
        {
            "text": "Group 1",
            "children": [
                {
                    "id": 1,
                    "text": "Option 1.1",
                },
                {
                    "id": 2,
                    "text": "Option 1.2"
                }
            ]
        },
        {
            "text": "Group 2",
            "children": [
                {
                    "id": 3,
                    "text": "Option 2.1"
                },
                {
                    "id": 4,
                    "text": "Option 2.2"
                }
            ]
        }
    ],
    "pagination": {
        "more": true
    }
};

function formatState(state) {
    if (!state.id) {
        var $state = $('<span>' + state.text + '</span>');
        $state.on('click', function(){
            let currentIds = $('#opt-select').select2('data').map(el => el.id);
            let newIds = state.children.map(el => el.id);
            $('#opt-select').val(currentIds.concat(newIds));
            $('#opt-select').trigger('change');
            $('#opt-select').select2('close');
        });
        return $state;
    }
    return state.text;
}

$(document).ready(function () {
    $("#opt-select").select2({
        data: something.results,
        templateResult: formatState,
    });
});
<select id="opt-select" style="width: 300px;" name="states[]" multiple="multiple"> </select>

相关问题