1

I'm creating a dynamic navigation menu on Codeiginter which retrieve from MYSQL DB Here is the description of navigation

Parent table

|---parent_id---link---title-----|
|---1-----------#------Parent1---|
|---2-----------#------Parent2---|
|---3-----------#------Parent3---|

Children table

|---children_id---fk_parent_id---title-------|
|--------1---------2-------------children1---|
|--------2---------2-------------children2---|
|--------3---------2-------------children3---|

Sub Children table (This sub child will show when children was selected)

|---sub_child_id--- fk_children_d ------title-------|
|------1--------------2-------------Sub Children1---|
|------2--------------2-------------Sub Children2---|
|------3--------------2-------------Sub Children3---|

Navigation menu

|---------|---------|--------|
| Parent1 |Parent2  |Parent3 |  
|---------|===++====|--------|
|=============++======================================|       
|---|Children1|-----|Children2|-----|Childrent3|------|
|-===================++===============================|
|-----------------|Sub Childrent1|--------------------|
|-----------------|Sub Childrent2|--------------------|
|-----------------|Sub Childrent3|--------------------|

Notes: As my below code it work only on Children but it don't show on sub Children

Here is my model function which to create some conditional for childrent and parent

function menu() {
        $this->db->select("*");
        $this->db->from("menu_parents");
        $q = $this->db->get();

        $final = array();
        if ($q->num_rows() > 0) {
            foreach ($q->result() as $row) {

                $this->db->select("*");
                $this->db->from("menu_childrent");
                $this->db->where("fk_p_id", $row->parents_id);
                $q = $this->db->get();
                if ($q->num_rows() > 0) {
                    $row->children = $q->result();
                    foreach ($q->result() as $srow){
                        //This is the session problem which I want to select for my sub children from menus_children
                        $this->db->select("*");
                        $this->db->from("menu_sub_childrent");
                        $this->db->where("fk_m_child_id", $srow->m_child_id);
                        $q = $this->db->get();
                        if($q->num_rows()>0){
                            $row->sub_children = $q->result();
                        }
                    }
                }
                array_push($final, $row);
            }
        }

        return $final;
    }

Here is my view

<ul class="nav navbar-nav">
                <?PHP foreach($menus as $menu): ?> 
                            <li class="dropdown megamenu-fullwidth"> 
                                <a data-toggle="dropdown" class="dropdown-toggle" href="#"> <?PHP echo $menu->title;?> <?PHP  if(isset($menu->children)):?><b class="caret"></b><?PHP endif;?></a>
                                 <?PHP  if(isset($menu->children)):?>
                                    <ul class="dropdown-menu">  
                                        <?PHP foreach($menu->children as $child): ?>
                                            <li class="megamenu-content">
                                                <ul class="col-lg-2 col-sm-2 col-md-2">
                                                    <li class="no-border"><p><strong><?PHP echo $child->title;?></strong></p></li>

                                                        <?PHP  if(isset($menu->sub_children)):?> 
                                                            <?PHP foreach($menu->sub_children as $sub_children): ?> 
                                                                <li><a href="#"> <?PHP echo $sub_children->title;  ?><br></a></li>
                                                            <?PHP endforeach;  ?>
                                                        <?PHP endif;?>

                                                </ul>
                                            </li>
                                        <?PHP endforeach;  ?>
                                    </ul>
                                 <?PHP  endif; ?>
                            </li>
                    <?PHP endforeach; ?>
            </ul>

Here is i Use Var_dump()

array (size=3)
  0 => 
    object(stdClass)[22]
      public 'parents_id' => string '1' (length=1)
      public 'linke' => string '' (length=0)
      public 'title' => string 'parent1' (length=7)
  1 => 
    object(stdClass)[23]
      public 'parents_id' => string '2' (length=1)
      public 'linke' => string '' (length=0)
      public 'title' => string 'parent2' (length=7)
      public 'children' => 
        array (size=6)
          0 => 
            object(stdClass)[26]
              ...
          1 => 
            object(stdClass)[25]
              ...
          2 => 
            object(stdClass)[27]
              ...
          3 => 
            object(stdClass)[28]
              ...
          4 => 
            object(stdClass)[29]
              ...
          5 => 
            object(stdClass)[30]
              ...
      public 'sub_children' => 
        array (size=1)
          0 => 
            object(stdClass)[33]
              ...
  2 => 
    object(stdClass)[24]
      public 'parents_id' => string '3' (length=1)
      public 'linke' => string '' (length=0)
      public 'title' => string 'parent1' (length=7)

Thanks advance for your help Sir

8
  • First point: Make your live easier and use one query for the whole navigation, instead of nested queries in loops. And the second one is: In your loops, youe are overriding $q. Commented Mar 10, 2015 at 5:18
  • I've try to create different of @q and $row it still not work.i amn't understand much about this Commented Mar 10, 2015 at 5:44
  • Pleas show a print_r($final) to see, that the array ist filled up right. Commented Mar 10, 2015 at 6:06
  • Oh when I used var_dump() function it doesn't show any value of my array. as my nest loop and mysql clause it show be show up why it doesn't show Commented Mar 10, 2015 at 6:18
  • Good look and try one query for the navigation, in the end it is easier. Commented Mar 10, 2015 at 6:23

1 Answer 1

1

I believe you need a result that looks something like this:

enter image description here

And to do that, you first need to modify your table to be something like this:

enter image description here

Once you have this, you can then create a model like this of which you can then send to your controller, then your view:

class Nav_m extends MY_Model {

    private $menus;
    private $keys_to_skip = array();

    function __construct() {
        parent::__construct();
    }

    public function menus() {
        $this->db->select("*");
        $this->db->from("nav");
        $this->q = $this->db->get();
        if ($this->q->num_rows() > 0) {
            return $this->q->result_array();
        }
    }

    public function navigation($selected = null) {
        $this->menus = $this->menus();
        $out = '<ul class="nav navbar-nav">';
        foreach ($this->menus as $k => $menu) {

//            var_dump($this->keys_to_skip);
            if (!in_array($k, $this->keys_to_skip)) {
                $class = (strcasecmp($menu['text'], $selected) == 0 ) ? "active " : "";
                $out .= $this->check_children($menu, $class);
            }
        }
        $out .= "</ul>";
        return $out;
    }

    function check_children($menu, $class) {

        if ($this->hasChildren($menu['id'])) {

            $class .="dropdown megamenu-fullwidth";
            $out = "<li class='$class'> <a href='{$menu['link']}'class='dropdown-toggle' data-toggle='dropdown'>" . $menu['text'] . "<b class='caret'></b>" . "</a>";
            $out .= $this->getChildren($menu['id']);
            $out .= "</li>";
        } else {
            $out = "<li class='$class'>";
            if ($menu['link'] != null) {
                $out .= "<a href='{$menu['link']}'>{$menu['text']}</a>";
            } else {
                $out .= "<span>" . $menu['text'] . "</span>";
            }
            $out .= "</li>";
        }
        return $out;
    }

    private function hasChildren($menu_id) {
        foreach ($this->menus as $menu) {
            if ($menu['show_condition'] && $menu['parent'] == $menu_id) {
                return TRUE;
            }
        }
        return FALSE;
    }

    private function getChildren($parent_id) {
        $has_subcats = FALSE;
        $out = "<ul class='dropdown-menu'>";
        $out .= "<li class='megamenu-content'>";
        foreach ($this->menus as $k => $menu) {
            if ($menu['show_condition'] && $menu['parent'] == $parent_id) {
                array_push($this->keys_to_skip, $k);
                $has_subcats = TRUE;
                $out .="<ul class='col-lg-2  col-sm-2 col-md-2 unstyled noMarginLeft'>";
                $out .= $this->check_childrens($menu, "");
                $out .= "</ul>";
            }
        }
        $out .= "</li>";
        $out .= "</ul>";
        return ( $has_subcats ) ? $out : FALSE;
    }

    function check_childrens($menu, $class) {

        if ($this->hasChildren($menu['id'])) {

            $class .="dropdown";
            $out = "<li><p><strong>".$menu['text']."</strong></p>";
            $out .= $this->getChildrens($menu['id']);
            $out .= "</li>";

        } else {
            $out = "<li class='$class'>";
            if ($menu['link'] != null) {
                $out .= "<a href='{$menu['link']}'>{$menu['text']}</a>";
            } else {
                $out .= "<span>" . $menu['text'] . "</span>";
            }
            $out .= "</li>";
        }
        return $out;
    }

    private function getChildrens($parent_id) {
        $out ='';
        foreach ($this->menus as $k => $menu) {
            if ($menu['show_condition'] && $menu['parent'] == $parent_id) {
                $out .= $this->check_childrens($menu, '');
                array_push($this->keys_to_skip, $k);
            }
        }
        return $out;
    }

}
Sign up to request clarification or add additional context in comments.

1 Comment

This is absolutely correct answer Thanks you very much Sir, My Problem 2 months now it was solved. I'm really thanks you.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.