Treeview con caricamento dinamico dei nodi 'figlio'
Dal link presente a fondo pagina è possibile scaricare un semplice esempio compatibile con tutte le versione di ASP.NET (1.0, 1.1 - 2.0) di treeview che permette la visualizzazione dei dati ad albero.
Il progetto è un'estensione dell'ottimo treeview presente sul portale www.constile.org il cui funzionamento è spiegato in questa pagina. Nel file zip è presente il progetto realizzato con Visual Studio 2003 composto principalmente da una pagina asp.net, un database Access nella directory "database", un web services ".asmx" in "webservices", il file "soapclient.js" per l'accesso da javascript al web services e la directory "images" contenenti le immagini per la visualizzazione dell'albero.
Decompresso l'archivio zip in una directory contrassegnata come directory virtuale in IIS e richiamata la pagina, otterremo questo risultato:
Nella parte sinistra è presente l'esempio originale preso da Constile, a destra lo stesso esempio ma con il carimaneto dinamico dei nodi figlio:
Le voci visualizzate all'interno dell'albero sono prese da un database Access con la seguente tabella:
Questa tabelle è composta da tre campi:
- id
- voce
- padre
L'id è l'indice univoco della tabella, voce è il campo descrittivo e padre è il record padre a cui fa riferimento la voce attuale. I record senza padri hanno come valore padre lo zero.
Parte fondamentale del funzionamento del tutto è il codice Javascript presente nella pagina:
<script type="text/javascript"><br /><!--<br />// Eseguito immediatamente<br />var url='<%=Url%>';
Qui viene definita una variabile client globale in cui sarà inserito l'url del del web services che il codice Javascript richiamerà per ottenere i nodi figlio dell'attuale. Url viene definita all'interno dell'evento Page_Load della pagina con questo codice:
Url="http://"+Request.Url.Host+"/treeview/webservices/ws.asmx";
Il codice successivo è quello utilizzato dall'esempio di Constile per l'apertura e la chiusura dei nodi figlio, con l'aggiunta del pre-caricamento delle immagini:
// Funzioni per l'albero<br />function mmenu(mID) {<br /> var menu = document.getElementById(mID);<br /> var display = menu.style.display;<br /> menu.style.display = (display == "block") ? "none" : "block";<br /> menu.parentNode.style.listStyleImage = (display == "block") ? "url(images/cartellachiusa.gif)" : "url(images/cartellaaperta.gif)";<br />}<br />window.onload = function() {<br /> // Precarica immagini<br /> if (document.images)<br /> {<br />var immagine1=new Image;<br />immagine1.src='images/cartellaaperta.gif';<br />var immagine2=new Image;<br />immagine2.src='images/cartellachiusa.gif';<br />var immagine3=new Image;<br />immagine3.src='images/doc.gif';<br /> }<br /> var uls = document.getElementsByTagName("ul");<br /> for (i=0;i<uls.length;i++) {<br />if(uls[i].className=="submenu")uls[i].style.display = "none";<br /> CreaTree('0');<br /> }<br />}
Dopo il carcimanto delle immagini, viene richiamato anche la funzione CreaTree('0') per il popolamento iniziale dei primi nodi figlio. Tale funzione è presente qui di seguito:
var attuale='';<br />function CreaTree(oggetto)<br />{<br /> attuale=oggetto;<br /> var espandere=window.document.getElementById(attuale);<br /> if (espandere.innerHTML=='')<br /> {<br />// Non c'è ancora nulla, carico...<br />espandere.innerHTML="Caricamento...";<br />mmenu(attuale);<br />var pl = new SOAPClientParameters();<br />pl.add("livello", oggetto);<br />SOAPClient.invoke(url, "CreaAlbero", pl, true, CreaTree_Back);<br /> }<br /> else<br />mmenu(attuale);<br />}<br />function CreaTree_Back(r)<br />{<br /> var espandere=window.document.getElementById(attuale);<br />if (espandere!=null)<br />espandere.innerHTML=r;<br />}<br />function Risultato(v)<br />{<br /> alert(v);<br />}<br />//--><br /></script>
Queste funzioni richiamano il web services grazie al "Javascript SOAP Client" realizzato da Matteo Casati, le cui info le si possono trovare a questo url.
Il codice del web services richiamato è molto semplice:
[WebMethod]<br />public string CreaAlbero(string livello)<br />{<br />System.Threading.Thread.Sleep(300);<br />DataTable dt;<br />if (livello.Length==1)<br />dt=Figli(0);<br />else<br />dt=Figli(Convert.ToInt32(livello.Substring(livello.LastIndexOf("-")+1)));<br />StringBuilder sb=new StringBuilder();<br />foreach (DataRow dr in dt.Rows)<br />{<br />// Controllo che abbia figli<br />if (dr["numero_figli"].ToString()=="0")<br />{<br />// Non ha figli<br />sb.Append("<li><a href='#' onclick='Risultato(\"");<br />sb.Append(dr["id"]);<br />sb.Append("\")'>");<br />sb.Append(dr["voce"]);<br />sb.Append("</li>\r\n");<br />}<br />else<br />{<br />// Ha figli<br />sb.Append("<li class='menu'>\r\n");<br />sb.Append("<a href=\"javascript:CreaTree('");<br />sb.Append(livello);<br />sb.Append("-");<br />sb.Append(dr["id"]);<br />sb.Append("')\">");<br />sb.Append(dr["voce"]);<br />sb.Append("</a>\r\n");<br />sb.Append("<ul class=\"submenu\" id='");<br />sb.Append(livello);<br />sb.Append("-");<br />sb.Append(dr["id"]);<br />sb.Append("' style=\"display = 'none';\"></ul>");<br />sb.Append("</li>\r\n");<br />}<br />}<br />return sb.ToString();<br />}
Lo Sleep iniziale è presente solo per controllare il corretto funzionamento in locale. Il parametro passato è il nodo padre, e da questo viene eseguita una query al database per ottenere i record figli, dai quali viene creato il codice HTML che sarà ritornato al codice Javascript e che sarà inserito nella pagina.
Da questo link è possibile scaricare l'esempio completo da riutilizzare e migliorare. Altre info le si possono trovare a questo blog.
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.