[PHP] DHTML Menu opbouwen

Pagina: 1
Acties:
  • 152 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Beekforel
  • Registratie: November 2001
  • Laatst online: 16:19

Beekforel

Is eigenlijk geen vis

Topicstarter
Ik ben een website aan het ontwikkelen en heb hierin een DHTML menu gemaakt. Dit menu heb ik gemaakt aan de hand van deze tekst.

Nou heb ik alle menu items in een tabel in de database staan, zodat het te beheren is met het CMS etc. Hier komt ook mijn probleem, De opbouw van het menu gaat niet goed.

De volgende functie gebruik ik om het menu op te bouwen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function buildMenu($var, $database) 
    {
        $selection = $database->handleQuery("SELECT * FROM category WHERE cat_childOf = '". $var . "' ORDER BY cat_title;");

        echo "<ul>";
            while($results = mysql_fetch_object($selection)){
                $temp = $results->cat_childOf;
                echo "<li>";
                echo "<a href=\"?category=$results->cat_id\">$results->cat_title</a>\n";
                if($temp != '0') { echo "</li>"; }
                buildMenu($results->cat_id, $database);
            }
        echo "</li></ul>";
    }

Een category heeft een id, een title en een childOf. Als de childOf 0 is is het een hoofditem, is het een getalletje dan is het een subitem van het hoofditem met dat id. Duidelijk?

In mijn pagina roep ik de functie aan:
PHP:
1
2
3
4
5
        <ul class="menu">
            <?PHP
                buildMenu("0", $database);          
            ?>
        </ul>


In de CSS is het menu gedefinieerd etc, dat zit op zich wel goed.

Alleen de output van de functie is een zootje:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        <ul class="menu">
            <ul><li><a href="?category=1">Advertenties</a>
<ul><li><a href="?category=18">Koop en verkoop</a>
</li><ul></li></ul><li><a href="?category=19">Oproepen</a>
</li><ul></li></ul><li><a href="?category=20">Vacatures</a>
</li><ul></li></ul></li></ul><li><a href="?category=2">Agenda</a>
<ul></li></ul><li><a href="?category=3">Attracties</a>
<ul><li><a href="?category=21">Doolhof</a>

</li><ul></li></ul><li><a href="?category=16">Vlooienmarkt</a>
</li><ul></li></ul></li></ul><li><a href="?category=4">Bedrijven</a>
<ul></li></ul><li><a href="?category=5">Evenementen</a>
<ul><li><a href="?category=23">Avondvierdaagse</a>
</li><ul></li></ul><li><a href="?category=22">Ballonvaarten</a>
</li><ul></li></ul></li></ul><li><a href="?category=6">Gebeurtenissen</a>
<ul></li></ul><li><a href="?category=7">Historie</a>
<ul></li></ul><li><a href="?category=8">Links</a>
<ul></li></ul><li><a href="?category=9">Sport</a>

<ul></li></ul><li><a href="?category=11">Vakantie</a>
<ul></li></ul><li><a href="?category=10">Verenigingen</a>
<ul><li><a href="?category=24">Biljart</a>
</li><ul></li></ul></li></ul></li></ul>     </ul>

en ik weet even niet hoe ik het anders moet opbouwen.

Het zou zo moeten maar ik krijg dat niet voor elkaar.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  <ul> 
    <li><a href="#">Home</a></li> 
    <li><a href="#">About</a> 
      <ul> 
        <li><a href="#">History</a></li> 
        <li><a href="#">Team</a></li> 
        <li><a href="#">Offices</a></li> 
      </ul> 
    </li> 
    <li><a href="#">Services</a> 
      <ul> 
        <li><a href="#">Web Design</a></li> 
        <li><a href="#">Internet Marketing</a></li> 
        <li><a href="#">Hosting</a></li> 
        <li><a href="#">Domain Names</a></li> 
        <li><a href="#">Broadband</a></li> 
      </ul> 
    </li>
    <li><a href="#">Contact Us</a> 
      <ul> 
        <li><a href="#">United Kingdom</a></li> 
        <li><a href="#">France</a></li> 
        <li><a href="#">USA</a></li> 
        <li><a href="#">Australia</a></li> 
      </ul> 
    </li> 
  </ul>


Nou heb ik het idee dat ik iets over het hoofd zie of totaal de plank mis sla maar ik zie het gewoonweg niet. Iemand van jullie misschien?

Nou zet ik het probleem er niet eens bij. Het menu werkt alleen in Firefox en daar komt bij ieder item een soort subitem met alleen een top border (als er geen subitem is).

[ Voor 33% gewijzigd door Beekforel op 14-08-2005 19:00 ]


Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
Probeer eens zo:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?
    function buildMenu($var, $database) 
    {
        $selection = $database->handleQuery("SELECT * FROM category WHERE cat_childOf = '". $var . "' ORDER BY cat_title;");
        echo "<ul>";
            while($results = mysql_fetch_object($selection)){
                $temp = $results->cat_childOf;
                echo "<li>";
                echo "<a href=\"?category=$results->cat_id\">$results->cat_title</a>\n";
                buildMenu($results->cat_id, $database);
                echo "</li>";
            }
        echo "</ul>";
    }
?>

[ Voor 19% gewijzigd door Skaah op 14-08-2005 18:58 ]


Acties:
  • 0 Henk 'm!

  • Beekforel
  • Registratie: November 2001
  • Laatst online: 16:19

Beekforel

Is eigenlijk geen vis

Topicstarter
Dan krijg ik dezelfde output. :?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<ul class="menu">
            <ul><li><a href="?category=1">Advertenties</a>

<ul><li><a href="?category=18">Koop en verkoop</a>
<ul></ul></li><li><a href="?category=19">Oproepen</a>
<ul></ul></li><li><a href="?category=20">Vacatures</a>
<ul></ul></li></ul></li><li><a href="?category=2">Agenda</a>
<ul></ul></li><li><a href="?category=3">Attracties</a>
<ul><li><a href="?category=21">Doolhof</a>
<ul></ul></li><li><a href="?category=16">Vlooienmarkt</a>
<ul></ul></li></ul></li><li><a href="?category=4">Bedrijven</a>
<ul></ul></li><li><a href="?category=5">Evenementen</a>

<ul><li><a href="?category=23">Avondvierdaagse</a>
<ul></ul></li><li><a href="?category=22">Ballonvaarten</a>
<ul></ul></li></ul></li><li><a href="?category=6">Gebeurtenissen</a>
<ul></ul></li><li><a href="?category=7">Historie</a>
<ul></ul></li><li><a href="?category=8">Links</a>
<ul></ul></li><li><a href="?category=9">Sport</a>
<ul></ul></li><li><a href="?category=11">Vakantie</a>
<ul></ul></li><li><a href="?category=10">Verenigingen</a>
<ul><li><a href="?category=24">Biljart</a>

<ul></ul></li></ul></li></ul>       </ul>

Acties:
  • 0 Henk 'm!

  • niwreG
  • Registratie: Augustus 2003
  • Laatst online: 17-10-2024

niwreG

^heeft dat geschreven->

volgens mij moet je een beetje meer spelen met \t en \n maar ik kan het zo even niet testen door een dode server

^^eventueele typfouten zijn als vermaak bedoeld


Acties:
  • 0 Henk 'm!

  • Vesta
  • Registratie: November 2004
  • Niet online
kijk eens naar str_repeat voor het inspringen.

Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12:57

Robtimus

me Robtimus no like you

niwreG schreef op zondag 14 augustus 2005 @ 19:36:
volgens mij moet je een beetje meer spelen met \t en \n maar ik kan het zo even niet testen door een dode server
\t (tab) en \n (line break) hebben hier niets mee te maken aangezien de meeste whtespace door de browser wordt genegeerd en als een enkele spatie wordt afgebeeld.

Je wilt alleen maar een submenu (ul) als er results zijn, dus je kunt proberen de eerste slag buiten de if te halen:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    function buildMenu($var, $database) 
    {
        $selection = $database->handleQuery("SELECT * FROM category WHERE cat_childOf = '". $var . "' ORDER BY cat_title;");

        if ($results = mysql_fetch_object($selection)){
            echo "<ul>";
            $temp = $results->cat_childOf;
            echo "<li>";
            echo "<a href=\"?category=$results->cat_id\">$results->cat_title</a>\n";
            buildMenu($results->cat_id, $database);

            // en nu dus de rest van de loop, dus records 2+
            while($results = mysql_fetch_object($selection)){
                $temp = $results->cat_childOf;
                echo "<li>";
                echo "<a href=\"?category=$results->cat_id\">$results->cat_title</a>\n";
                buildMenu($results->cat_id, $database);
            }
            // sluit de <ul> af
            echo "</ul>";
        }
    }
Hier maak ik gebruik van 2 dingen:
  1. Je hoeft een <li> niet af te sluiten. Als je die er wel bij wilt zet je die vlak na buildMenu
  2. while ( B ) { S } is gelijk aan if ( B ) { S }; while ( B ) { S }. Dat kan worden herschreven als if ( B ) { S; while ( B ) { S } } else { while ( B ) { S } }. Omdat in de else geldt !B kan dat deel worden weggelaten.
edit:
extra spaties gezet om niet van ( B ) een smiley te maken.

[ Voor 12% gewijzigd door Robtimus op 14-08-2005 19:56 ]

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • Beekforel
  • Registratie: November 2001
  • Laatst online: 16:19

Beekforel

Is eigenlijk geen vis

Topicstarter
_O_
Het werkt. Ik snap je code niet helemaal maar het werkt wel.
Nou nog in IE, daar gaat iets mis met de javascript maar dat terzijde.

Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12:57

Robtimus

me Robtimus no like you

Beekforel schreef op zondag 14 augustus 2005 @ 20:01:
_O_
Het werkt. Ik snap je code niet helemaal maar het werkt wel.
Nou nog in IE, daar gaat iets mis met de javascript maar dat terzijde.
Je had eerst een while loop, met de <ul> erbuiten. Dat houdt dus in dat er altijd een <ul> geprint wordt, of er nou wel of geen submenu nodig is. Je wilt alleen maar de <ul> als er een submenu nodig is, maw: als je minimaal 1 result hebt.

Dan over het afsplitsen van de eerste row. Bekijk het eens vanuit het oogpunt van een for (zelfde principe).
Stel je hebt de volgende code:
PHP:
1
2
3
for ($i = 0; $i < count($arr); $i++){
    // doe iets met $arr[$i]
}
Maar stel je wilt iets speciaals doen als $i = 0. Dan kun je binnenin je loop controleren of $i = 0, maar dat moet dan elke slag. Je kan ook geval $i = 0 erbuiten halen:
PHP:
1
2
3
4
5
6
if (count($arr) > 0){
    // $arr[0] bestaat, dus doe het speciale met $arr[0]
}
for ($i = 1; $i < count($arr); $i++){
    // doe het gewone met $arr[$i]
}
Dan nog even een laatste kleine aanpassing; als count($arr) = 0 dan zal de loop nooit uitgevoerd worden. Dus kun je schrijven
PHP:
1
2
3
4
5
6
7
if (count($arr) > 0){
    // doe iets met $arr[0]
    // loop nu - dit kan alsnog 0 keer zijn als er maar 1 element is, maar dat boeit niet
    for ($i = 1; $i < count($arr); $i++){
        // doe iets met de overige elementen van $arr
    }
}
Vervang $arr door je result set, weet dat na $result = mysql_fetch_object($selection) $result het $i-de record is van je query, en de analogie is zo gevonden.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 18-09 16:28

Bosmonster

*zucht*

Tipje overigens:

Haal eerst je data op met 1 query en loop daar doorheen voor het opbouwen van je menu. Nu loop je met een query en dat is niet echt wat je noemt efficient (tenzij je de boel ook cached, maar dan nog zou ik voor de eerste optie kiezen).

[ Voor 11% gewijzigd door Bosmonster op 14-08-2005 21:12 ]


Acties:
  • 0 Henk 'm!

  • Dennis
  • Registratie: Februari 2001
  • Laatst online: 15:52
IceManX schreef op zondag 14 augustus 2005 @ 19:54:
[/code]Hier maak ik gebruik van 2 dingen:
  1. Je hoeft een <li> niet af te sluiten. Als je die er wel bij wilt zet je die vlak na buildMenu
Ja, hier wil ik dus nog even op reageren want ook een <li> moet, net zoals alle andere html-tags, gewoon netjes worden afgesloten in bepaalde versies van html (te weten xhtml). Dus afhankelijk van het DTD type moet het dus wél. Het is om die reden een goede gewoonte om jezelf aan te leren altijd alle tags af te sluiten, ook al gebruik je géén xhtml doctype.

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

Dennis schreef op zondag 14 augustus 2005 @ 21:23:
Ja, hier wil ik dus nog even op reageren want ook een <li> moet, net zoals alle andere html-tags, gewoon netjes worden afgesloten in bepaalde versies van html (te weten xhtml). Dus afhankelijk van het DTD type moet het dus wél. Het is om die reden een goede gewoonte om jezelf aan te leren altijd alle tags af te sluiten, ook al gebruik je géén xhtml doctype.
offtopic:
helemaal mee eens, echter let wel op dat je tags als <br> etc _niet_ gaat sluiten op het moment dat je geen XHTML DTD gebruikt ;)
IceManX schreef op zondag 14 augustus 2005 @ 19:54:
[...]
\t (tab) en \n (line break) hebben hier niets mee te maken aangezien de meeste whtespace door de browser wordt genegeerd en als een enkele spatie wordt afgebeeld.
ehm, het kan aan mij liggen hoor, maar die extra white space _wil_ je juist wel als je aan het developen bent, het werkt een stuk prettiger met nette source :)

Acties:
  • 0 Henk 'm!

  • Robtimus
  • Registratie: November 2002
  • Laatst online: 12:57

Robtimus

me Robtimus no like you

Dennis schreef op zondag 14 augustus 2005 @ 21:23:
Ja, hier wil ik dus nog even op reageren want ook een <li> moet, net zoals alle andere html-tags, gewoon netjes worden afgesloten in bepaalde versies van html (te weten xhtml). Dus afhankelijk van het DTD type moet het dus wél. Het is om die reden een goede gewoonte om jezelf aan te leren altijd alle tags af te sluiten, ook al gebruik je géén xhtml doctype.
Mjah, je hebt gelijk, ik ken XHTML ook wel (gebruik het alleen niet (vaak)). Maar daarom zette ik ook erbij WAAR je hem zou moeten sluiten.
Erkens schreef op zondag 14 augustus 2005 @ 21:30:
ehm, het kan aan mij liggen hoor, maar die extra white space _wil_ je juist wel als je aan het developen bent, het werkt een stuk prettiger met nette source :)
Ja daar ben ik het wel mee eens, maar het heeft weinig met het probleem an sich te maken.

Tip voor de TS als hij dit wilt: neem een extra paramter $depth die begint met een constante (bv 0, 4, wat jij wilt voor een goede alignment.). Je roept dan buildMenu intern aan met $depth + 1 om het aantal spaties / tabs te bepalen.

More than meets the eye
There is no I in TEAM... but there is ME
system specs


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

IceManX schreef op zondag 14 augustus 2005 @ 22:25:
Ja daar ben ik het wel mee eens, maar het heeft weinig met het probleem an sich te maken.
ik denk dat die whitespace juist alles met het probleem te maken heeft.
Door het toevoegen van die paar tabs/spaties/line ends creeer je overzicht waardoor je vaak sneller ziet waar het fout gaat, in zo'n onoverzichtelijke brij HTML kan je namelijk niet snel zien waar het fout gaat.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Ik gebruik vaak voor debug-doeleinden de functionaliteit auto-indent in mijn editor. Daar kan je gewoon je zooi-output inzetten en dan wordt het leesbaar gemaakt. Zeker in dit soort gevallen aan te raden.
Pagina: 1