Avatar billede erik_a Novice
14. juli 2009 - 21:26 Der er 6 kommentarer og
1 løsning

Automatisk generering af treemenu

Hejsa

Sidder her og skal ha lavet en treemenu.
I ved :
Menu 1
Menu 2
  Menu 2.1
  Menu 2.2
    Menu 2.2.1
  Menu 2.3
Menu 3

Menuen skal styres af en database med følgende felter : id, parent, description.

Da jeg ikke på forhånd ved hvor mange undermenuer der bliver kan jeg ikke løbe igennem databasen x antal gange.
Kan forestille mig at de skal gøres så min treeview funktion kalder sig selv et antal gange.
Det jeg mangler er ideen til hvordan jeg gør dette.
Har lavet lidt kode der godtnok løber igennem og skriver rigtig nok ud, men jeg mangler at kunne afslutte en treemenu igen.

Her er min nuværende kode :

function treeview_parent($webmenu_id){

    $sql = "SELECT description, webmenu_id, parent FROM webmenu WHERE webactive = '1' AND parent = '$webmenu_id' ORDER BY sorting";
    $result = dbQuery($sql);
    while($row = dbFetchAssoc($result)){
        extract($row);
        if(treeview_is_child($webmenu_id)){
            echo "<br>".$description." - ".$webmenu_id." - ".$parent."{";
            treeview_parent($webmenu_id);
        }else{
            echo "<br>".$description." - ".$webmenu_id." - ".$parent;
           
           
        }
    }
}
function treeview_is_child($parent){
    $sql = "SELECT description, webmenu_id, parent FROM webmenu WHERE webactive = '1' AND parent = '$parent' ORDER BY sorting";
    $result = dbQuery($sql);
    return dbNumRows($result);
}   


treeview_parent();

Her er min nuværende output :
Webshop - 000 - {
Pålæg - 010 - 000
Brød - 020 - 000
Mælkeprodukter - 030 - 000{
Ost - 101 - 030{
Ost 45% - 103 - 101
Smør - 102 - 030
Kød - 040 - 000

Ønskede output :
Webshop - 000 - {
Pålæg - 010 - 000
Brød - 020 - 000
Mælkeprodukter - 030 - 000{
Ost - 101 - 030{
Ost 45% - 103 - 101}
Smør - 102 - 030}
Kød - 040 - 000}

Den endelige manu skal så se således ud :
Webshop
  Pålæg
  Brød
  Mælkeprodukter
    Ost
      Ost 45%
    Smør
  Kød

Bliver selvfølgelig i den færdige version udviddet til en del mere, det er bare en lille smule test data jeg har i øjeblikket.
Det ender selvfølgelig op med at være flere end de 4 niveauer der er nu, ved ikke hvor mange, men det skal være muligt.

Håber i ved hvad det er jeg mener og har en ide/løsning til mig, for jeg har stirret mig lidt blind på det nu :-(

På forhånd tak
/Erik_A
Avatar billede repox Seniormester
14. juli 2009 - 22:59 #1
Det er for mange en uoverskuelig opgave at lave rekursive funktioner.
Men ofte er det faktisk meget nemmere end det ser ud.

Du har delt din rekursive funktion op i to, selvom det absolut ikke er nødvendigt.

Her er mit eksempel på at lave det du mangler:

<?php

    function menu_tree($parent = 0)
    {
       
        $sql = "SELECT * FROM test WHERE parent = ".$parent;
        $res = mysql_query($sql);
        if(mysql_num_rows($res) == 0)
            return null;
   
        echo "<ul>";
       
        while($obj = mysql_fetch_object($res))
        {
                echo "<li>";
                echo $obj->description;
                menu_tree($obj->id);
                echo "</li>";
        }   
       
        echo "</ul>";
       
    }
   
    menu_tree();


?>

Du vil nok hurtigt kunne tilpasse den dit databaselag og de tabeltilpasninger du har lavet.

Grunden til at jeg har valgt at smide det ud i en <ul> liste er at det er 'moderne' - forstået sådan at du vil kunne tilpasse det hurtigt til en menu styret af CSS og så kan du også se det overblik du har skabt i din menu.
Avatar billede erik_a Novice
15. juli 2009 - 10:08 #2
Hey repox.

Vil du da straks sende et svar så jeg kan kvittere for det perfekte svar ;-)

1000 mange tak, og din kode er da en del mindre end min kæmpe lange kode :-)

/Erik
Avatar billede repox Seniormester
15. juli 2009 - 10:11 #3
Jamen, jeg er da glad for at kunne hjælpe :)
Avatar billede jakobdo Ekspert
15. juli 2009 - 15:45 #4
Jeg ville nok lave et udtræk og smide alt indhold i et array og så lave min rekursive funktions kald mod array.
Du kan jo ende med en milliard opslag mod din sql, alt efter hvor mange menu punkter du måtte have. :o)
Avatar billede repox Seniormester
15. juli 2009 - 19:45 #5
Jeg kan kun give dig ret - jeg ved faktisk ikke hvorfor jeg ikke lige gik i den retning; jeg var nok farvet af det eksisterende forslag.
Avatar billede erik_a Novice
16. juli 2009 - 11:09 #6
Hmm, hvordan skulle det så udformes?
Kan godt se det smarte i at begrænse opslagene i databasen.
Ved ikke om det er muligt at smide flere point efter jer, ellers må jeg jo oprette et nyt spørgsmål.
Avatar billede jakobdo Ekspert
16. juli 2009 - 11:33 #7
Selve det store opslag kunne jo laves ved:

$menu_array = array();
$res = mysql_query("SELECTdescription, webmenu_id, parent FROM webmenu WHERE webactive = '1' AND parent = '$parent' ORDER BY sorting");
while($row = mysql_fetch_assoc($res)){
$menu_array[$row['webmenu_id']] = array('description' => $row['description'], 'webmenu_id' => $row['webmenu_id'], 'parent' => $row['webmenu_id']);
}

Så vil du få et array med alle dine menu elementer.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester