0

I'm working with a method that builds navigation for my site through recursion and I'm having trouble adding style. The way my method is built I can't seem to figure out a way to make the parent a parent class and the child a child class so in CSS I can style the two. In case it will make things easier to understand here is an example of my database:

enter image description here

Here's an example of the output I'm trying to achieve:

<ul>
    <li class="parent">Parent
    <ul>
        <li class="child">Child 1</li>
        <li class="child">Child 2</li>
        <li class="child">Child 3</li>
        <li class="child">Child 4</li>
    </ul>
    </li>
</ul>

The current code puts child in every instance of <li>. I've tried many different things and this is killing me. Here's the code:

/* i'm using pdo to pull all the categories out of MySQL, NULL means it will be a parent category */
$array = $categoryVIEW->fetchAll(PDO::FETCH_ASSOC);
$this->buildSide($array,NULL)

private function buildSide($items,$parent)
{
    $hasChildren = false;
    $outputHtml = '<ul>%s</ul>';
    $childrenHtml = ''; 
    foreach($items as $item)
    {
        if ($item['parent'] == $parent)
        {
            $hasChildren = true;
            $childrenHtml .= '<li><a href="?c='.$item['category_id'].'">'.$item['category_name'];         
            $childrenHtml .= $this->buildSide($items,$item['category_id']);         
            $childrenHtml .= '</a></li>';           
        }
    }
    if (!$hasChildren)
    {
        $outputHtml = '';
    }
    return sprintf($outputHtml,$childrenHtml);      
}

I'm sure it's something easy, but I'm stuck :(

Thanks for having a look!

UPDATE

I've been playing around with my code and added a conditional to check for the $parent being NULL and if so make $class a parent, otherwise make $class child. The problem I'm having is I'm getting an unwanted <ul></ul> after every child? What's weird is when I change $child = false; it eliminates my erroneous <ul></ul>, but makes everything parent.

private function buildSide($array,$parent)
{       
    $child = ($parent === NULL)?false:true;
    $html  = '';
    $tag   = '<ul>%s</ul>'; 
    $class = ($child)?'child':'parent'; 

    foreach($array as $item)
    {
        if($item['parent'] === $parent)
        {
            $child = true;
            $html .= '<li class="'.$class.'">'.$item['category_name'];
            $html .= $this->buildSide($array,$item['category_id']);
            $html .= "</li>\n";
        }
    }
    if(!$child)
    {
        $tag = '';
    }
    return sprintf($tag,$html);
}
Mike
  • 1,760
  • 5
  • 21
  • 40
  • How are you calling this to start the process? And what is the data structure for the `$items` array? It might help to break down the problem with a separate example to highlight the issue. – jheddings Oct 28 '12 at 05:09
  • Hey jheddings, thanks for having a look. I updated my code to help better understand what I'm trying to achieve. – Mike Oct 28 '12 at 17:56

1 Answers1

0

UPDATE based on your edits

If I understand what you are trying to achieve, you may need to do this in two passes... Since the parent field in your database creates an implicit hierarchy from a flat tree, you may need to first construct the hierarchy in order to get the desired output. Since you are rendering the HTML as the data elements are processed, you will not be able to guarantee the hierarchy is preserved when rendering your lists.

Instead, you will need to generate a heirarchy that matches your parent / child relationship stored in the database. There are several topics here that address this process (for example). Once you have a tree structure that matches your implicit DB structure, generating the HTML to match should be fairly straightforward.

Community
  • 1
  • 1
jheddings
  • 26,717
  • 8
  • 52
  • 65
  • I'm playing with your code now and I will get back with what I come up with ;) – Mike Oct 28 '12 at 17:57
  • I tried the code and it works, but it doesn't add the `parent` and `child`. It adds the `category_id` where I want the CSS class name. – Mike Oct 28 '12 at 19:39
  • What are you using to determine your CSS class name? Do you have a predetermined set for parent and children, or is it based on your DB content? I don't see where you are adding the CSS class in your example, so I'm not sure how you are calculating it. – jheddings Oct 29 '12 at 04:17
  • Thanks for responding. I actually decided to get away from recursion since this is only one deep. This new process works well, but I can't seem to figure out how to show only the sub categories for the selected category. See my edit ;) – Mike Oct 29 '12 at 04:22