jQuery Select2 具有多个嵌套组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26146848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 11:14:05  来源:igfitidea点击:

Select2 with multiple nested groups

jqueryjquery-select2

提问by Fábio Freitas

I'm having trouble using the Select2 with various groups, only the latter appears.

我在将 Select2 与各种组一起使用时遇到问题,只有后者出现。

<select name="txtConta" id="txtConta" data-placeholder="Selecione a conta">         
    <option value=""></option>
    <option value="S11892">2 - Gastos</option>
    <option value="S11893">2.1 - DESPESA OPERACIONAL FIXA</option>
    <option value="S11895">2.1.1 - PESSOAL</option>
    <option value="S11915">2.1.1.1 - GERENCIA/ADMINSTRATIVO</option>
    <option value="11916">2.1.1.1.1 - SAL&#193;RIOS</option>
    <option value="11917">2.1.1.1.2 - DIVIDENDOS / COMISS&#213;ES /BONUS</option>
    <option value="11918">2.1.1.1.3 - INSS</option>
    <option value="11919">2.1.1.1.4 - FGTS</option>
    <option value="11920">2.1.1.1.5 - IRRF COD. 0561</option>
    <option value="11921">2.1.1.1.6 - PLANO DE SAUDE</option>
    <option value="11922">2.1.1.1.7 - TICKET REFEICAO</option>
    <option value="11923">2.1.1.1.8 - VALE TRANSPORTE</option>
    (...)
</select>

<script>
$('select').each(function () {
    $(this).select2({
        allowClear: true,
        width: 'resolve',
        dropdownAutoWidth: true
    });
});

$('#txtConta').find('option').each(function () {
    if ($(this).attr("value").indexOf('S') == 0) {
        $('<optGroup/>').attr('label', $(this).text()).appendTo($('#txtConta'));
        $(this).remove();
    } else {
        $('#txtConta').find('optGroup').last().append($(this));
    }
});
</script>

You can see a demonstration in this jsfiddle.

你可以在这个jsfiddle 中看到一个演示。

回答by Wilson

This solution was tested using select2 version 4.0.1, and you can do this way:

此解决方案已使用 select2 版本 4.0.1 进行了测试,您可以这样做:

  1. Pass one array that contains one attribute more (the levelof every node in the hierarchy). The array's structure is simple

  2. Create a function to format results,that is, how looks like every item according its level inside of hierarchy

  3. When initialize select, set the function created to attribute templateResult

  1. 传递一个包含一个属性多种(一个阵列级别的每个节点的层次结构中的)。数组的结构很简单

  2. 创建一个函数来格式化结果,即每个项目在层次结构中的级别如何

  3. 初始化select时,将创建的函数设置为属性templateResult

You can see in the follow code:

您可以在以下代码中看到:

  $(document).on("ready", function() {
  var data = [{
    id: "2",
    text: "2 - Gastos",
    level: 1
  }, {
    id: "2.1",
    text: "2.1 - DESPESA OPERACIONAL FIXA",
    level: 2
  }, {
    id: "2.1.1",
    text: "2.1.1 - PESSOAL",
    level: 3
  }, {
    id: "2.1.1",
    text: "2.1.1 - PESSOAL",
    level: 4
  }, {
    id: "2.1.1.1",
    text: "2.1.1.1 - GERENCIA/ADMINSTRATIVO",
    level: 4
  }, {
    id: "2.1.1.1.1",
    text: "2.1.1.1.1 - SALáRIOS",
    level: 5
  }, {
    id: "2.1.1.1.2",
    text: "2.1.1.1.2 - DIVIDENDOS / COMISS?ES /BONUS",
    level: 5
  }, {
    id: "2.1.1.1.3",
    text: "2.1.1.1.3 - INSS",
    level: 5
  }, {
    id: "2.1.1.1.4",
    text: "2.1.1.1.4 - FGTS",
    level: 5
  }];

  function formatResult(node) {
    var $result = $('<span style="padding-left:' + (20 * node.level) + 'px;">' + node.text + '</span>');
    return $result;
  };

  $("#mySelect").select2({
    placeholder: 'Select an option',
    width: "600px",
    data: data,
    formatSelection: function(item) {
      return item.text
    },
    formatResult: function(item) {
      return item.text
    },
    templateResult: formatResult,
  });
});
<!DOCTYPE html>

<html>

<head runat="server">
  <title></title>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.2-rc.1/css/select2.min.css" rel="stylesheet" />
</head>

<body>
  <select id="mySelect">
  </select>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.1/js/select2.full.min.js"></script>
</body>
</html>

回答by Fábio Freitas

I used like this. Working Fine.

我是这样用的。工作正常。

$(document).on("ready", function() {
  function formatResult(node) {
    var level = 0;
    if(node.element !== undefined){
      level = (node.element.className);
      if(level.trim() !== ''){
        level = (parseInt(level.match(/\d+/)[0]));
      }
    }
    var $result = $('<span style="padding-left:' + (20 * level) + 'px;">' + node.text + '</span>');
    return $result;
  };

  $("#select2").select2({
    placeholder: 'Select an option',
    width: "300px",
    templateResult: formatResult,
  });
});
<!DOCTYPE html>

<html>

<head runat="server">
  <title></title>
  <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/css/select2.min.css" rel="stylesheet" />
</head>

<body>
  <select id="select2" data-placeholder="Select an option" tabindex="-1" aria-hidden="true">
  <option></option>
  <optgroup label="Base">
    <option class="level_0" value="0">Base Parent</option>
  </optgroup>
  <option class="level_1" value="11">A</option>
  <option class="level_2" value="12">Ant</option>
  <option class="level_3" value="15">Fire Ant</option>
  <option class="level_2" value="14">Apple</option>
  <option class="level_1" value="13">B</option>
</select>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.3/js/select2.min.js"></script>
</body>
</html>

回答by Luís Cruz

Take a look at this GitHub issue. What matters is

看看这个 GitHub 问题。重要的是

HTML itself forbids nesting <optgroup>s, so your markup is invalid before it even reaches Select2. However, you can arbitrarily nest choices via children when you use JS objects to represent the choices.

HTML 本身禁止嵌套<optgroup>,因此您的标记在到达 Select2 之前就无效了。但是,当您使用 JS 对象来表示选择时,您可以通过子项任意嵌套选择。

This means that you can use childrento get multiple nested options. The following solution and jsfiddle are based on fperie's solution.

这意味着您可以使用children获取多个嵌套选项。以下解决方案和 jsfiddle 基于fperie解决方案

<input name="txtConta" id="txtConta" data-placeholder="Selecione a conta" />     

<script>
var data = [
    {id: "2", name: "2 - Gastos", children: [
        {id: "2.1", name: "2.1 - DESPESA OPERACIONAL FIXA", children: [
            {id: "2.1.1", name: "2.1.1 - PESSOAL", children: [
                {id: "2.1.1", name: "2.1.1 - PESSOAL"}, 
                {id: "2.1.1.1", name: "2.1.1.1 - GERENCIA/ADMINSTRATIVO", children: [
                    {id: "2.1.1.1.1", name: "2.1.1.1.1 - SALáRIOS"},
                    {id: "2.1.1.1.2", name: "2.1.1.1.2 - DIVIDENDOS / COMISS?ES /BONUS"},
                    {id: "2.1.1.1.3", name: "2.1.1.1.3 - INSS"},
                    {id: "2.1.1.1.4", name: "2.1.1.1.4 - FGTS"}
                ]}
            ]}
        ]}
    ]}
    ];

$('#txtConta').select2({
    allowClear: true,
    width: 'resolve',
    dropdownAutoWidth: true,
    width: '400px',
    data: {results: data, text: "name"}, 
    formatSelection: function(item) { 
        return item.name 
    }, 
    formatResult: function(item) { 
        return item.name 
    }
});
</script>

With this solution the leafs are still selectable. If you don't want to select the leafs you should remove the idattribute from the leafs.

有了这个解决方案,叶子仍然是可选择的。如果您不想选择叶子,则应id从叶子中删除该属性。

See this JSfiddlethat demonstrates both configurations. Take note that I've only used a portion of the data you provided.

请参阅演示这两种配置的JSfiddle。请注意,我只使用了您提供的部分数据。

回答by Kiran Ramaswamy

I tried adding this as a comment to Saravanan's post above, but the length of the comment was too long, so consider this as an expansion to his post, and credit goes to him for giving me the idea.

我尝试将此作为评论添加到上面 Saravanan 的帖子中,但评论的长度太长,因此将其视为对他帖子的扩展,感谢他给了我这个想法。

This is a bit of a necro post from me, but just wanted to expand on how I implemented the above solution with the newer jquery format of $document.ready instead of $document.on. Slightly modified as well, since I have mine nested in a pageLoad, and thus the function is outside the pageLoad, and I used an attribute rather than a class. Important part though, is that I had to put both templateResult and templateSelection for it to work, as without the latter, nothing happened:

这是我的一个死者帖子,但只是想扩展我如何使用 $document.ready 而不是 $document.on 的较新 jquery 格式实现上述解决方案。也稍作修改,因为我将我的嵌套在 pageLoad 中,因此该函数在 pageLoad 之外,并且我使用了属性而不是类。重要的部分是,我必须同时使用 templateResult 和 templateSelection 才能使其工作,因为没有后者,什么也没有发生:

function pageLoad() {
    $(document).ready(function () {
        $(".multiple-group").select2({
            allowClear: true,
            closeOnSelect: false,
            templateResult: formatResult,
            templateSelection: formatResult
        });
    });    
}

function formatResult(node) {
    var level = 0;
    if (node.element !== undefined) {
        level = node.element.getAttribute("hierarchy-level");
        if (level.trim() !== '') {
            level = parseInt(level) - 1;
        }
    }

    var $result = $('<span style="padding-left:' + (15 * level) + 'px;">' + node.text + '</span>');
    return $result;
}