Select2 with multiple nested groups

风流意气都作罢 提交于 2019-12-18 16:49:24

问题


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

<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.


回答1:


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

  1. Pass one array that contains one attribute more (the level of 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

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>



回答2:


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>



回答3:


Take a look at this GitHub issue. What matters is

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.

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

<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 id attribute from the leafs.

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




回答4:


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.

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:

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;
}


来源:https://stackoverflow.com/questions/26146848/select2-with-multiple-nested-groups

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!