Menu/Submenus from DB


#1

Hi..im trying to create a menu structure from 2 database tables. Using mysql, i could query a record for the initial loop, and add another loop within in it using <?php do { ?>.

Now that ive mode onto PDO im having an issue, well, i understand that queries must be finished before another can start, so i thought of joining the tables and structuring the output.

The output structure should be:

Start repeat C1
<li>

<ul>
Start repeat C2
<li></li>
End repeat C2
</ul>

<li>
End repeat C1

Although the query i have is correct (i can echo c1 title and underneath echo all the available subtitles from C2) and having a nightmare with the structure...that the final </ul> </li> are part of the count and are outputted to the number of records from C2, rather than just closing the structure before the end of the C1 loop

The code so far is:

<?php 
$sql ="SELECT 
       n1.cat1id
     , n1.c1_tit_it
     , n2.c2_tit_it
     FROM n_cat1 n1
        JOIN n_cat2 n2 ON n1.cat1id = n2.cat1link
     ORDER BY c1_tit_it, c2_tit_it";

$res = $pdo->query($sql);

	  
	  $current = '';
foreach ($res as $row) {
	
	$c1 = str_replace(" ", "-", $row['c1_tit_it']);
	$c2 = str_replace(" ", "-", $row['c2_tit_it']);
 

   if ($row['c1_tit_it'] != $current) {
		
 echo '<li class="has-dropdown">
			<a href="#">'.$c1.'</a>
			<ul>';

        $current = $row['c1_tit_it'];  
		

    }

    echo '<li><a href="#">'.$c2.'</a></li>';
	
	
	?> </ul> </li><?php   // This is the problem area
				
								
}
	  ?>

I hope someone is available to help me on this...so near, yet so far at the moment


#2

I would think that what you would need to do is:

  • inside your if-then to see if c1_tit_it has changed, check if $current is blank, if it is not, close the <ul> and <li> tags.

  • at the end of the loop, if they've been opened, close the <ul> and <li> tags again.

At the moment you seem to close ul and li every time you go around the loop, not just when the c1 category changes.


#3

Hi droopsnoot, thats not quite the issue....when i look at the source, the first record prints:

<li class="has-dropdown">
<a href="#">Bagno</a>
<ul>
<li><a href="#">Ceramica-per-il-bagno</a></li></ul></li>
<li><a href="#">Complementi-per-il-bagno</a></li></ul></li>
<li><a href="#">Mobili-per-il-bagno</a></li></ul></li>

whereas should be:

<li class="has-dropdown">
<a href="#">Bagno</a>
<ul>
<li><a href="#">Ceramica-per-il-bagno</a></li>
<li><a href="#">Complementi-per-il-bagno</a></li>
<li><a href="#">Mobili-per-il-bagno</a></li>
</ul>
</li>

So, basically its adding the ul li to each of the C2 li's, rather than adding a UL LI at the end of each complete record (C1)


#4

Yes, that's exactly what I said:

So you need to close the ul and li tags as part of the code you run when C1 changes, before you open the li and ul, if you've already got one open, close it there. To clarify, inside this if-then clause:

  if ($row['c1_tit_it'] != $current) {
 // before you open the new li/ul
 // see if there's already one open
 // and close it if there was.

#5

Hi..sorry im stuck :(....i think you need to hold my hand with this one...ive been looking at it for so long ive gone blind..looking at the main loop:

foreach ($res as $row) {
	
	$c1 = str_replace(" ", "-", $row['c1_tit_it']);
	$c2 = str_replace(" ", "-", $row['c2_tit_it']);

   if ($row['c1_tit_it'] != $current) {
		
 echo '<li class="has-dropdown">
			<a href="#">'.$c1.'</a>
			<ul>';

        $current = $row['c1_tit_it'];  
    }

    echo '<li><a href="#">'.$c2.'</a></li>';
	
	}

The first IF condition is closed before i echo the C2 li's...the C2s li's are part of the initial foreach loop...therefore i need a way to echo the final ul li after the C2 li's, however outside the IF loop, but within the the foreach loop...is that possible...sorry if im being thick :slight_smile: ...any alternatives would be truly welcomed at this point :slight_smile:


#6

Pseudo-code:

listopen = false;
foreach loop () { 
  do your strreplace here
  if (c1 has changed) { 
    if (listopen ==true) {
      output closing ul and li tags
      listopen = false
      } // end of whether a list was open
    output opening list and ul tags as you do now
    listopen = true
  } // end of whether c1 has changed
 output li element for c2
 remember value of c1 for comparison
} // end of foreach() loop
if (listopen == true) {
  output closing ul and li tags
  }

The structure is exactly the same as the structure you have already, just with a flag added to say whether you've opened a list, so you know whether to close it or not, and some code to close if before you open a new on, and at the very end.


closed #7

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.