Not able to manage/create a Adjacency Model,


#21

@cryptichorizon. Thanx again for the reply. Stupid me :frowning: That should be NULL and indeed did the trick :slight_smile: :+1: Leaves me with one last question about the foreach loop and included if statement:

	foreach ($results as $menu_item){
		$return .= '<li class="'.$menu_item['item_class'].'">';
			$return .= '<a class="' . $menu_item['link_class'] . '" title="' . $menu_item['title'] . '" href="' . $menu_item['url'] . '">' . $menu_item['label'] . '</a>';
			$subs = $this->build_menu_items($language_abbr, $menu_item['id']);	
			if ( is_null($menu_item['parent_id'])) {
				$return .=	$subs;	
			} else {
				$return	.=  '<div class="dropdown-menu">';
					$return .=	$subs;
				$return .=	'</div>';	
			}
		$return .= '</li>';		
	}

Using it this way it is now it is not showing me a drobdown menu, instead it shows me 2 menu items (parent_id = null) followed by de dropdown items (inline) followed by the next menu items (parent_id = null). See applied screenshot:

Not sure where I’m going wrong within the foreach loop

Again thank you for the rest. I now at least understand the principle.

Edit: I figured out what the reason is for the strange behavior. I use Bootstrap so I need to adjust the layout and classes a bit. Again thank you a lot for your input and patience. I learned a lot the last couple of days.


#22

@cryptichorizon. :frowning: I was a bit to early with cheering. I adjusted the styles for the dropdown section. So instead of a div I used the more traditional ul tag:

$return	.=  '<ul class="dropdown-menu">';
    $return .=	$subs;
$return .=	'</ul>';

But the if/else statement:

if ( is_null( $menu_item['parent_id'] )) {
	$return .=	$subs;	
} else {
	$return	.=  '<ul class="dropdown-menu">';
		$return .=	$subs;
	$return .=	'</ul>';	
}

is not right. This is what it returns after looking in the source:

<li class="nav-item dropdown">
	<a class="nav-link dropdown-toggle categorieen" title="Categorieën" href="">Categorieën</a>
		<li class="dropdown-item">
			<a class="dropdown-link antiek" title="Robin Gerard Antiek" href="/nl/antiek">Antiek</a>
				<ul class="dropdown-menu"></ul>
		</li>
		<li class="dropdown-item">
			<a class="dropdown-link boeken" title="Robin Gerard Boeken" href="/nl/boeken">Boeken</a>
				<ul class="dropdown-menu"></ul>
		</li>
		// other items
</li>

So instead of the main item (Categorieën) having a dropdown menu all sub items are holding a empty dropdown menu. What should I adjust? Thank you in advance.

Edit: Funny enough! I switched the content from the if/else statement arround:

if ( is_null($menu_item['parent_id'])) {
	$return	.=  '<ul class="dropdown-menu">';
		$return .=	$subs;
	$return .=	'</ul>';		
} else {
		$return .=	$subs;	
}

and now it is working. Only mayby, if you have the time, you can explain to me why that is? Because I would like to understand the principle and the other way arround looked more logic to me

Edit: As I said, it’s works now. But when I look at the source, there is a empty dropdown menu for every main item (parrent_id = null) that doesn’t have children. What do I have to change in the order / design to prevent this. Thanks


#23

Did a few changes to the code, it look a little messy but without knowing the rest of your code its hard to refactor.

To use it, just put it like this:

echo '<ul>';
echo $class->build_menu_items('EN', null);
echo '</ul>';

It should automatically render the menu, from parent to child levels.

Note. You should really consider changing your div from the dropdown to just be a ul, and just base the css rules on the level it is on.

Note. I assume the navigation is created by you upon site creation, and cannot be edited by client. If client can edit it, you should escape the values.

public function build_menu_items($language_abbr, $parent_id=null)
{
  if ($parent_id === null) {
    $restrict = 'AND `parent_id` IS NULL';
    $restrict_data = array($language_abbr);
  }
  else {
    $restrict = 'AND `parent_id`=?';
    $restrict_data = array($language_abbr, $parent_id);
  }

  $sql = "SELECT `id`
					 , `label`
		             , `title`
					 , `item_class`
					 , `link_class`
					 , `url`
					 , `parent_id`
					 , `lang`
				  FROM `site_navigation` 
				 WHERE `lang` = ?
				   {$restrict}";

  $stmt 		= 	$this->pdo->prepare($sql);
  $stmt->execute($restrict_data);
  $results	=	$stmt->fetchAll(PDO::FETCH_ASSOC);

  $return		=	'';

  foreach ($results as $menu_item){
    $return .= '<li class="'.$menu_item['item_class'].'">';
    $return .= '<a class="' . $menu_item['link_class'] . '" title="' . $menu_item['title'] . '" href="' . $menu_item['url'] . '">' . $menu_item['label'] . '</a>';

    $subs = $this->build_menu_items($language_abbr, $menu_item['id']);

    if (!empty($subs)) {
      $return	.=  '<ul class="dropdown-menu">';
      $return .=	$subs;
      $return .=	'</ul>';
    }

    $return .= '</li>';
  }

  return $return;
}

#24

@TheRedDevil. I am more than happy with the changes you made :grin: and it didn’t look messy at all :+1:

I noticed that using a div messed things up, and the reason why, the way you explain it, makes sense, so I changed the tag for the dropdown indeed to ul.

You assumed right :slight_smile: client can’t change the navigation so no problems there.

I like the the if/else statement before actual query and it makes a lot of sense, I only didn’t know/was not aware that you could use the AND statement and the execute command in such a way. That offers a lot of possibilities.

The if statement makes a lot of sense. Without the help of @cryptichorizon I wouldn’t have gotten this far, but with this if statement I have something like oh yes of course

In other words. This works great. I would like to thank both, you and @cryptichorizon very much. I learned a lot the last couple of days.