• User Attivo

    Menù ad albero con database

    Buongiorno.
    avrei bisogno di costruire un menù ad albero dinamico con un database mysql che si espande quando clicco sulla voce selezionata.
    Ho trovato qualcosa in giro, ma non riesco a creare in modo correto la funzione ricorsiva che quando clicco su un nodo padre si espande e mi fa vedere i nodi figli e i nodi a pari livello di quelli cliccato.
    Qualcuno sa aiutarmi?

    Il mio database è di questo tipo
    id (intero autoincrement)
    Nome
    Id_padre

    Grazie in anticpo a chi mi potrà aiutare


  • User Attivo

    Per prima cosa avrai bisogno dello script in java scritto sotto

    function startmenu()
    {
        document.getElementById('menu1').style.display = "none";
        document.getElementById('menu2').style.display = "none";
    }
    
    function menufunc(menuId)
    {
        if(document.getElementById(menuId).style.display == "none")
        {
            startmenu();
            document.getElementById(menuId).style.display = "block";
        }
        else
        {
            startmenu();
        }
    }
    

    Questo script è riferito a due menu ad albero cioè **menu1 **e menu2.

    Poi ricorro all'estrapolazione dei dati dal DB in cui controllo se il link ha un sottomenu. Esempio

    [PHP]$ssql = "SELECT * FROM tabella ORDER BY id";
    $resultid = mysql_query($ssql,$conn);
    $ssql_C = "SELECT COUNT(*) FROM tabella WHERE id_padre!=''; // CONTO I RECORD CON SOTTOLINK PENSO CHE id_padre CONTENGA UN VALORE PER IL SOTTOLINK
    $resultid_C = mysql_query($ssql_C,$conn);
    $row_C = mysql_fetch_row($resultid_C);
    $tot_C = $row_C[0]; // TOTALI RECORD SOTTOLINK
    $XY = 1;

    while (($campo=mysql_fetch_object($resultid))) // WHILE 1
    {
    $nome = strip_tags($campo->nome);
    $id_padre = strip_tags($campo->id_padre);

    if ($id_padre == "") // CONTROLLO SE CI SONO ALTRI LINK SOTTO QUELLO SCELTO
    {
    echo "<a href='pagina.php' target='_parent'><b>$nome</b></a><br>";
    }
    else // ELSE 1
    {
    if ($tot_C == 1) // CONTROLLO I TOTALI DEI RECORD TROVATI PER L'INCREMENTO DEL JAVASCRIPT SOTTOSTANTE $XY++
            {
            echo "<a href=\"javascript:menufunc('menu1')\"><b>$nome</b></a><br>";
            echo "<div id='menu1'>";
            }
        else
            {
            echo "<a href=\"javascript:menufunc('menu" . $XY . "')\"><b>$nome</b></a><br>";
            echo "<div id='menu" . $XY . "'>";
            $XY++;
            }
    

    // ADESSO PENSO AVRAI BISOGNO DI UN'ALTRA TABELLA IN CUI SONO SCRITTI I LINK DEL SOTTOMENU IN QUESTIONE
    $ssql2 = "SELECT * FROM tabella_sottolink WHERE id_padre='$id_padre' ORDER BY id"; // SELEZIONO I SOTTOLINK NELLA TABELLA PRESCELTA
    $resultid2 = mysql_query($ssql2,$conn);
    while (($campo2=mysql_fetch_object($resultid2))) // WHILE 2
    {
    $nome_aux = strip_tags($campo2->nome_aux);
    $link_url_aux = strip_tags($campo2->link_url_aux);
    echo "<a href='$link_url_aux'>$nome_aux</a><br>";
    } // CHIUDO WHILE 2
    echo "<br>";
    echo "</div>";
    } // CHIUDO ELSE
    } // CHIUDO WHILE[/PHP]
    Naturalmente se si trattasse di più di due sottomenu basterebbe aggiungere allo script Java, in alto, gli altri menu. Es.: menu3, menu4, menu5 ...... ecc...

    Se il discorso l'ho afferrato ed è esauriente sarei contento altrimenti fatti risentire per ulteriori chiarimenti.

    Ciao.


  • User Attivo

    Ciao...Innanzitutto ti ringrazio...però purtroppo credo che cosi non va bene nel mio caso perchè io vorrei poter gestire "infinite" categorie e sottocategorie e a priori non so quanti livelli è il mio menù...mi credi?? Sto impazzendo.
    Ho trovato qualcosa...

    <font face="Courier New"><font color="#0000bb">[php]<?

    require "connect.php";

    function output_categorie($id_principale)
    {
    $sql = "SELECT * FROM downcat WHERE id_principale = "$id_principale"";
    $res = mysql_query($sql);

    echo "<ul>";
    while ($row = mysql_fetch_assoc($res))
    {
    echo "<li>";
    echo "<a href=apricat.php?".$row['id_cat'].">".$row['nome']."</a>";

    //Stampa sottocategorie
    output_categorie($row['id_cat']);

    echo "</li>";
    }
    echo "</ul>";
    }

    if(isset($_GET['id'])){
    $id=$_GET['id'];
    $sql = "SELECT * FROM downcat WHERE id_cat = "$id"";
    $res = mysql_query($sql);

    echo "<ul>";
    while ($row = mysql_fetch_assoc($res))
    {
    echo "<li>";
    echo "<a href=apricat.php?".$row['id_cat'].">".$row['nome']."</a>";
    echo "</li>";}
    output_categorie($id);
    echo "</ul>";
    }
    else output_categorie(0);
    ?> [/php]
    Però il problema è che questo script mi fa vedere sempre e solo la categoria che ho cliccato....esempio

    cat1
    -cat2.1
    -cat2.1.1
    -cat2.1.2
    cat3
    -cat3.1
    cat4

    Io vorrei invece che inizialmente veda

    cat1
    cat3
    cat4

    Se clicco su cat1

    vorrei vedere
    cat1
    -cat2.1
    cat3
    cat4 ecc ecc

    So che la faccenda è complicata.....la ricorsione non è mai stato il mio forte.
    Ciao.


  • User

    Ciao, se posso darti un mio consiglio è inutile e altamente rallentante ricorrere al database per un menu...io opterei per un sano php+xml+js...a dirla tutta mi hai dato l'ispirazione per scrivere un tutorial che appunto utilizza una funzione ricorsiva per un menu ad infinite metavoci dacci un'occhiata:

    [..]
    Ciao.


  • User Attivo

    Ciao.
    Dove posso scaricare questo tutorial??
    Magari trovo la soluzione...
    Grazie


  • User

    Edit:

    • Inizia i messaggi ocn una maiuscola e termina con un punto.

  • User

    Eh mi hanno 'censurato' la fonte ...
    Comunque da qui:
    [...]


  • ModSenior

    Ciao GreyFox.

    Non sei assolutamente stato censurato, è stato semplicemente applicato il Regolamento del Forum GT, che ti ricordo hai accettato in ogni suo punto all'atto della tua iscrizione e che hai ben pensato di infrangere nuovamente dopo che il ModSenior ti aveva semplicemente editato l'url autopromozionale senza ulteriori conseguenze!
    Quì sul Forum GT esistono delle regole e se le rispettano gli altri non vedo perché non debba farlo anche tu. Si chiama rispetto!

    Hai un po' di tempo per pensarci su, rileggerti il Regolamento ed, eventualmente, decidere di tornare per rispettarlo.


  • User Newbie

    Per rendere il codice dinamico basta semplicemente modificare la prima risposta di amadeusorrento:

    function startmenu(menuId){
       document.getElementById(menuId).style.display = "none";
    }
    
    
    function menufunc(menuId)
    {
       if(document.getElementById(menuId).style.display == "none")
       {
           startmenu(menuId);
           document.getElementById(menuId).style.display = "block";
           
       }
       else if(document.getElementById(menuId).style.display == "block")
       {
           startmenu(menuId);
           document.getElementById(menuId).style.display = "none";
           
       } else 
       {
           startmenu(menuId);
       }
    }
    

    La parte di PHP (procedurale) copio il mio codice che ho riadattao alla mia tabella.

    Io ho un'unica tabella contenente sia i padri che i figli ovvero :[TABLE="width: 100"]

    [TD]padre1[/TD]
    [TD]figlio1[/TD]
    [/TR]

    [TD]padre1[/TD]
    [TD]figlio2[/TD]
    [/TR]

    [TD]padre1[/TD]
    [TD]figlio3[/TD]
    [/TR]

    [TD]padre2[/TD]
    [TD]figlio4[/TD]
    [/TR]

    [TD]padre2[/TD]
    [TD]figlio5[/TD]
    [/TR]

    [TD]...[/TD]
    [TD]...[/TD]
    [/TR]

    [TD]padreN[/TD]
    [TD]FiglioN[/TD]
    [/TR]
    [/TABLE]

    In caso diverso basta solo cambiare la prima query
    La funzione $connect effettua la connessione al mio database
    [PHP]
    $query = "SELECT DISTINCT padre FROM figlio order by padre";
    $connection = connect($query);
    $risultato = mysql_query($query);
    while ($campi=mysql_fetch_array($risultato))
    {
    $campo[]=$campi;
    }
    foreach($campo as $key=>$row)
    {
    $nome = $row['padre'];
    echo "<a href="javascript:menufunc('menu".$key."')"><b>$nome</b></a><br>";
    echo "<div id='menu".$key."' style="display: none;">";
    $query = "SELECT Figlio FROM tabella WHERE Padre='".$row['Padre']."' group by Figlio ";
    $connection = connect($query);
    $risultato = mysql_query($query);
    while($campo2 = mysql_fetch_array($risultato))
    {
    $nome_aux = $campo2['Figlio'];
    echo "<p style="margin-left: 40px; margin-right: 40px;">$nome_aux</p>";
    }
    echo "</div>";
    }
    [/PHP]
    la parte qui di seguito evidenziata
    *echo "<div id='menu".$key."' style="display: none;">"; *
    serve per visualizzare i padri tutti chiusi, se invece si vuole visualizzare la lista dei padri tutti aperti basta modificarlo in style="display: block;".

    Spero di essere stata più chiara possibile.