In questo paragrafo vediamo le dinamiche dell’albero per controllare il suo comportamento a runtime tramite eventi e metodi. Alcuni comportamenti verranno gestiti mediante la datamap del nodo dell’albero che ne coordina l’accesso ai dati.
Un esempio di utilizzo degli alberi è nel progetto di esempio North Wind Web che è possibile trovare nella sezione Documentazione della Console di Instant Developer Cloud.
Quando un albero viene aperto è possibile gestire manualmente o automaticamente il caricamento dei dati agendo sulla datamap legata al nodo di livello base.La proprietà autoload della datamap per default è settata a true ma è possibile impostarla a false e poi gestire il caricamento dei dati nell’evento onLoad della videata dopo aver indicato gli opportuni filtri.
Configurazione della visualizzazione dei nodi #
In molti casi è necessario modificare lo stile di un singolo nodo dell’albero in funzione del contenuto del record collegato, a tal fine è possibile utilizzare l’evento onRowComposition della datamap di caricamento del nodo.
Se per esempio volessimo colorare di rosso la label dei nodi dei prodotti sotto scorta di un albero che li visualizza potremmo utilizzare il seguente codice:
$EmployeeDM.onRowComposition = function(row, template)
{
$productTreeNode.style.color =
(row.UnitsInStock < row.ReorderLevel) ? "red" : "";
};
Accesso ai dati del nodo attivo #
Se si desidera accedere ai dati che alimentano il nodo di un albero è possibile recuperare il documento sotteso dalla datamap facendo riferimento a this.row.document nel caso la datamap sia basata sui documenti.
Altrimenti per un albero con datamap che dipende da una query a da proprietà in memoria si recuperano i dati della riga attiva mediante this.row.nome-proprietà, dove nome-proprietà è il nome del campo che si vuole utilizzare così come riportato nella query.
Se si vuol accedere ai dati di un nodo dell’albero quando esso viene attivato e impostare la caption dell’albero della toolbar con la label del nodo attivo è possibile utilizzare l’evento onNodeActivated dell’albero.
$idfTree.onNodeActivated = function(event)
{
this.caption = event.treeNode.label;
};
Nel caso venga utilizzato l’evento onActivated del nodo invece che quello dell’albero faremo riferimento a this.label per la label del nodo e a this.row.document per il documento relativo.
Al momento del caricamento dei dati di un albero tramite la sua datamap occorre sapere che non esiste un nodo attivo e quindi se vogliamo attivare il primo nodo dell’albero alla sua apertura lo dobbiamo fare utilizzando questo codice nell’evento onLoad della videata.
App.CategoriesTree.prototype.onLoad = function(options)
{
yield $idfTreeDatamap.load();
$idfTreeDatamap.position = 0;
let doc = $idfTreeDatamap.row.document;
let node = yield $idfTree.findNode({CategoryID : doc.CategoryID});
node.activate();
};
Nell’esempio viene caricata la datamap che alimenta il nodo, attivata la prima riga della datamap, recuperato il documento relativo della posizione, recuperata l’istanza del nodo e su questa richiamato il metodo che lo attiva.
Il metodo findNode permette di cercare un nodo in base a svariati parametri che è possibile visualizzare nella reference all’interno dell’ide di Instant Developer Cloud premendo F1 una volta selezionato il metodo nell’albero del progetto.
Nella libreria IDFWidgets è possibile visualizzare tutti i metodi ed eventi degli elementi IdfTree e IdfTreeNode per una più esaustiva lista delle possibilità di manipolazione di questi oggetti.
La proprietà activeNode di un albero restituisce il nodo attivo dell’albero e può essere utilizzata per recuperarne i dati e utilizzarli in altre parti di una videata.
Selezione multipla #
Gli alberi supportano la selezione multipla dei dati e tale opzione è attivabile impostando a true la proprietà ShowMultipleSelection.
I nodi dell’albero selezionati sono controllabili tramite interfaccia utente o da codice. In questo secondo caso è possibile usare il metodo, di albero o di nodo, changeAllNodesSelection per cambiare la selezione di tutti i nodi.
La proprietà selected del nodo indica se quel nodo è selezionato o meno e può essere modificata per cambiarne la selezione.
Per permettere di personalizzare la modifica della selezione l’albero notifica l’evento onNodeSelectionChanged e il singolo nodo notifica l’evento onSelectionChanged tutte le volte che un nodo cambia stato di selezione oppure se è stato usato un comando di cambiamento della selezione complessivo.
Nel caso si debbano eseguire operazioni sui nodi selezionati di un albero è possibile utilizzare il metodo getSelectedNodes dell’albero che restituisce un array contenente i nodi selezionati.
Drag & drop #
In un albero è possibile attivare l’utilizzo del drag & drop, per spostare un nodo su un altro nodo, mediante l’impostazione a true delle proprietà CanDrag e CanDrop dell’elemento IdfTree.
Sull’elemento nodo abbiamo la proprietà Draggable che indica che esso è trascinabile su altri elementi, e la proprietà Droppable che indica se è possibile trascinare elementi su di esso.
Nell’immagine sottostante possiamo vedere un drag & drop di un prodotto nell’albero delle categorie.

Le operazioni di drag & drop gestiscono automaticamente lo spostamento del nodo dalla collection di partenza a quella di destinazione.
Non occorre quindi eseguire operazioni specifiche per avere le strutture delle datamap aggiornate e se esse dipendono da documenti è sufficiente utilizzare il metodo save della datamap per aggiornare i dati e rendere effettivo lo spostamento.
Quindi se abbiamo un documento Category che ha una collection figlia Products di documenti Product e su questa struttura costruiamo un albero avremo la situazione dell’immagine sottostante.

L’albero idfTree ha le proprietà canDrag e canDrop impostate a true, il nodo categoriesTreeNode ha la proprietà Droppable impostata a true e il nodo productsTreeNode ha le proprietà Draggable e Droppable impostate a true. Quindi è possibile trascinare nodi prodotto su nodi categoria e altri nodi prodotto.
Trascinando un nodo prodotto su un nodo categoria avremo come risultato che la collection Products della categoria di destinazione conterrà il prodotto trascinato in ultima posizione.
Se invece si trascina un nodo prodotto su un altro nodo prodotto si avrà l’effetto di aver spostato quest’ultimo di posizione nella collection relativa della datamap.
Una volta effettuato il drag & drop è possibile eseguire il salvataggio del documento spostato per consolidare la modifica sul database. Tale operazione si può realizzare mediante apposito bottone nell’interfaccia utente oppure utilizzando l’evento onDataChange della datamap.
Nell’evento quindi possiamo controllare se la datamap è in stato modificato ed effettuare un salvataggio della stessa così da riportare le modifiche sul database.
$categoriesDM.onDataChange = function()
{
if ($categoriesDM.modified) {
yield $categoriesDM.save();
}
};
Quando invece spostiamo un documento Product su un altro documento Product della stessa categoria questo cambia posizione all’interno della datamap Products e quindi è possibile aggiornare un eventuale campo sequenza che ne determina l’ordine di visualizzazione.
Per interagire con le operazioni di drag & drop ed eventualmente annularle si utilizza l’evento onDrop, presente sia a livello di albero che di nodo.
L’evento onDrop dell’albero riceve come parametri sia il nodo trascinato che quello su cui è stato rilasciato, mentre l’evento onDrop del nodo riceve come parametro l’elemento che è stato trascinato.
Nel caso di evento onDrop sull’albero per il trascinamento di un nodo del documento Product su un nodo del documento Category potremmo scrivere il seguente codice per impedire lo spostamento di un prodotto sulla categoria con id uguale a 1.
$idfTreeCategories.onDrop = function(event)
{
if (event.dragElement.row instanceof App.NwindBE.Product &&
event.dropElement.row instanceof App.NwindBE.Category) {
let nodeDrag = event.dragElement.row; //type:NwindBE.Product
let nodeDrop = event.dropElement.row; //type:NwindBE.Category
//
if (nodeDrop.CategoryID === 1) {
event.skip = true;
yield app.popup({
type : "toast",
message : "Spostamento non ammesso"
});
}
}
};
Nell’esempio viene controllato che il nodo di provenienza sia di un documento di tipo Product e quello di destinazione sia di tipo Category, quindi sono recuperati i relativi documenti e se la categoria di destinazione è la 1 viene annullata l’operazione e visualizzato un messaggio.
Navigazione tramite interfaccia utente #
L’albero visualizzato in una videata è navigabile da tastiera in modo che l’utilizzatore possa spostarsi tra i suoi nodi mediante i tasti freccia, espandere o contrarre nodi dell’albero e attivare un nodo senza dover usare il mouse.
Ecco un elenco dei comandi di navigazione possibili:
- freccia su e giù – spostamento tra i nodi dell’albero
- freccia destra – espansione del nodo corrente, se il nodo è già espanso sposta la selezione sul primo nodo figlio
- freccia sinistra – contrazione del nodo corrente, se il nodo selezionato è un figlio la selezione torna al nodo padre
- enter – attivazione del nodo corrente
- barra spaziatrice – nel caso di multi selezione attiva, seleziona o deseleziona il nodo