Como posso selecionar o nó infantil programaticamente, no Dynatree?
-
26-09-2019 - |
Pergunta
Estou usando o JQuery's Dynatree no meu aplicativo e quero selecionar todos os nós filhos programaticamente quando um nó pai for selecionado. A estrutura da minha árvore é a seguinte
<div id = "tree">
<ul>
<li>package 1
<ul>
<li>module 1.1
<ul>
<li> document 1.1.1</li>
<li> document 1.1.2</li>
</ul>
</li>
<li>module 1.2
<ul>
<li>document 1.2.1</li>
<li>document 1.2.2</li>
</ul>
</li>
</ul>
</li>
<li> package 2
<ul>
<li> module 2.1
<ul>
<li>document 2.1.1</li>
<li>document 2.1.1</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
Agora, o que eu quero é que, quando clico no nó da árvore com o título "Pacote 1" todos os seus nós filhos, ou seja, (Módulo 1.1, documento 1.1.1, documento 1.1.2, módulo 1.2, documento 1.2.1, documento 1.2.2) também deve ser selecionado.
Abaixo está a abordagem que tentei usar:
$("#tree").dynatree({
onSelect: function(flag, dtnode) {
// This will happen each time a check box is selected/deselected
var selectedNodes = dtnode.tree.getSelectedNodes();
var selectedKeys = $.map(selectedNodes, function(node) {
//alert(node.data.key);
return node.data.key;
});
// Set the hidden input field's value to the selected items
$('#SelectedItems').val(selectedKeys.join(","));
if (flag) {
child = dtnode.childList;
alert(child.length);
for (i = 0; i < child.length; i++) {
var x = child[i].select(true);
alert(i);
}
}
},
checkbox: true,
onActivate: function(dtnode) {
//alert("You activated " + dtnode.data.key);
}
});
No if(flag)
Condição Eu recebo todos os nós filhos do elemento selecionado pelo usuário e me dá o valor correto que posso ver na instrução ALERT (Child.length). Então eu corro o loop para selecionar todas as crianças, mas o loop nunca vai além da declaração var x = child[i].select(true);
E eu nunca posso ver a declaração alert(i)
sendo executado. O resultado da afirmação acima é que, se eu selecionar o pacote 1, o módulo 1.1 e o documento 1.1.1 também for selecionado, mas nunca executa o alert(i)
Declaração - Nenhum outro filho do pacote 1 é selecionado. Na minha opinião, quando a primeira vez child[i].select(true)
A declaração é executada, também desencadeia o evento On Select de seus filhos, fazendo um tipo de coisa de recursão
Meu pensamento está correto? Não importa que recursão ou que diabos faça, ela não completa o loop e executa a próxima instrução alert(i)
.
Por favor me ajude a resolver esse problema. Estou morrendo de vontade de ver esse alerta, qualquer sugestão e ajuda é muito apreciada.
Solução
Mal testou, mas você pode tentar algo assim:
$(function(){
var inEventHandler = false;
$("#tree").dynatree({
checkbox: true,
selectMode: 2,
[...]
onSelect: function(select, dtnode) {
// Ignore, if this is a recursive call
if(inEventHandler)
return;
// Select all children of currently selected node
try {
inEventHandler = true;
dtnode.visit(function(childNode){
childNode.select(true);
});
} finally {
inEventHandler = false;
}
}
Outras dicas
Embora não seja um especialista das capacidades internas de Dynatree, escrevi algum código que gera trilhas de pão para o nó clicado e todos os seus descendentes.
No exemplo abaixo, clicar em "Edibles" seria lançado:
edibles
edibles > fruits
edibles > fruits > apples
edibles > fruits > apples > green apples
edibles > fruits > apples > green apples > granny smith
edible > vegetables
edible > vegetables > potatoes
Ao clicar em "maçãs verdes", produziria:
edibles > fruits > apples > green apples
edibles > fruits > apples > green apples > granny smith
Você pode se inspirar neste exemplo e recuperar os campos necessários em todos os documentos de crianças e gerar sua saída HTML.
O código está neste tópico:Melhor maneira de gerar trilhas de pão de texto a partir de uma matriz PHP com 3 colunas (ID, Path, Name)?
O script PHP em si é chamado do manipulador de eventos ONATIVATE DE DYNATREE através de um jQuery.ajax({...});
consulta.
Use a seguinte função no lugar de uma de Mar10's responda.
Todos os nós da criança são selecionados/não selecionados no nó pai Selecionar/Unselect.
onSelect: function (isSelected, node) {
node.visit(function (childNode) {
childNode.select(isSelected);
});
},