Select2 with multiple nested groups

I'm having problems using Select2 with various groups, only the last one 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 the demo in this jsfiddle .

+4
source share
4 answers

This solution has been tested using select2 version 4.0.1, and you can do it like this:

  • Skip one array that contains one more attribute (level each node in the hierarchy). Array structure is simple

  • Create a function to format the results, that is, what each element looks like, corresponding to its level inside the hierarchy

  • select , templateResult

:

  $(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>
Hide result
+8

. .

$(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>
Hide result
+2

GitHub. ,

HTML <optgroup> s, , Select2. , , JS .

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

. , id .

JSfiddle, . , .

+1

Saravanan , , , .

This is a slightly necropic post from me, but just wanted to expand on how I implemented the above solution with the new jquery format $ document.ready rather than $ document.on. Slightly modified since I have nested in pageLoad, and therefore the function is outside of pageLoad, and I used the attribute, not the class. The important part, however, is that I had to use both the Result and templateSelection templates to work, since nothing happened without the latter:

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

All Articles