具有多个嵌套组的 Select2
Posted
技术标签:
【中文标题】具有多个嵌套组的 Select2【英文标题】:Select2 with multiple nested groups 【发布时间】:2014-11-26 14:48:53 【问题描述】:我在将 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ÁRios</option>
<option value="11917">2.1.1.1.2 - DIVIDENDOS / COMISSÕ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看到一个演示。
【问题讨论】:
【参考方案1】:此解决方案使用 select2 4.0.1 版本进行了测试,您可以这样做:
传递一个包含多个属性的数组(层次结构中每个节点的级别)。数组的结构很简单
创建一个函数来格式化结果,即根据层次结构中的每个项目的级别看起来如何
初始化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>
【讨论】:
嗨,我试过你的代码,它对我有用。但我有一个问题,列表没有排序。我该如何克服这个问题?? 如何设置选中的选项?? @amine 您可以使用插件 select2 设置选定的选项:$('#mySelect2').val('1'); // Select the option with a value of '1'
$('#mySelect2').trigger('change'); // Notify any JS components that the value changed
请参阅select2.org/programmatic-control/add-select-clear-items【参考方案2】:
我是这样用的。工作正常。
$(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>
【讨论】:
作品完美。如果您的数据源是 HTML 而不是 JSON,则很好的解决方案。【参考方案3】:看看this GitHub issue。重要的是
HTML 本身禁止嵌套
<optgroup>
s,因此您的标记在到达 Select2 之前就无效了。但是,当您使用 JS 对象表示选项时,您可以通过子项任意嵌套选项。
这意味着您可以使用children
来获取多个嵌套选项。以下解决方案和jsfiddle基于fperie的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。请注意,我只使用了您提供的部分数据。
【讨论】:
感谢回复,我的数据是通过数据库来的,所以下拉列表携带。我不明白我怎么能做到这一点。 好吧,您可以从数据库中检索数据并创建一个具有 Select2 所需格式的 JSON 对象,而不是仅仅回显 再次感谢您,我不具备执行此操作的 jQuery 知识,如果您有其他想法,我将不胜感激。拥抱 是否有可能去一个下拉列表并在这个结构中重新制作它? 你不需要 jQuery。如果您使用的是 php,您可以使用键id
、name
和 children
创建一个多维数组,然后对数组执行 json_encode
。你的 data
变量,在 javascript 中,将是 json_encode 的结果。我假设很多,因为我不知道你的整个过程。如果您愿意,我可以在您添加所有需求和代码(即查询数据库的代码)后,在 *** em Português 中提供完整的答案。【参考方案4】:
我尝试将此作为评论添加到上面 Saravanan 的帖子中,但评论的长度太长,因此请将此视为对他帖子的扩展,感谢他给我的想法。
这是我的一个 necro 帖子,但只是想扩展我如何使用 $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;
【讨论】:
以上是关于具有多个嵌套组的 Select2的主要内容,如果未能解决你的问题,请参考以下文章