具有多个嵌套组的Select2

时间:2014-10-01 17:14:34

标签: jquery jquery-select2

我在使用各种组的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>

您可以在此jsfiddle中看到演示。

4 个答案:

答案 0 :(得分:11)

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

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

  2. 创建一个格式化结果的函数,即根据层次结构内的每个项目看起来如何?

  3. 初始化选择时,将创建的功能设置为属性 templateResult

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

      $(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>

答案 1 :(得分:3)

我是这样用过的。工作得很好。

&#13;
&#13;
$(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,
  });
});
&#13;
<!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>
&#13;
&#13;
&#13;

答案 2 :(得分:2)

看看this GitHub issue。重要的是

  

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

这意味着您可以使用children来获取多个嵌套选项。以下解决方案和jsfiddle基于fperie&#39; 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>

使用此解决方案,叶子仍然是可选择的。如果您不想选择叶子,则应从叶子中删除id属性。

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

答案 3 :(得分:1)

我试着在上面的Saravanan帖子中添加这个评论作为评论,但是评论的篇幅太长了,所以认为这是对他的帖子的扩展,并且他给了我这个想法。

这是我的一篇文章,但我想扩展一下如何使用$ document.ready的新jquery格式而不是$ document.on来实现上述解决方案。稍微修改,因为我已经嵌套在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;
}