1

I have Main product category Listed Like

  1. Cake
  2. List item
  3. Bun
  4. Toffees
  5. Bread

Under one Main product category there are sub products too.

1 Cake (1.1 Butter Cake)(1.2 Chocolate cake)

On my view I echo these main Products only by using following code.

<div class="row">
        <?php if(isset($records)) : foreach($records as $row) : ?>
            <div class="span2">
                <p class="text-center subheader"><?php echo $row->main_products_cat_name; ?>
                </p>
                <p class="text-center">
                    <a href="<?php echo base_url()?>product/all_product_data?id=<?php echo $row->main_products_cat_id;?>"><img src="<?php echo base_url(); ?>assests/images/products/main_products/<?php echo $row->main_products_cat_image; ?>" alt="<?php echo $row->main_products_cat_name; ?>" width="200px" height="200px">
                    </a>
                </p>
            </div>          
        <?php endforeach; ?>
        <?php endif; ?>
</div>

Can some one help me to echo Sub product category under Main Product.

3
  • can you show us the table(s) and the query that you used to get the $records from ? the question is not clear , in your $records , we can only understand that you have the main category id and image, do you have all the subcategories inside it too ? we don't know, so the database schema and the used query should be a part of the question, and then you will have an answer for sure ! Commented Jul 19, 2015 at 12:38
  • @Baci it's not hard to use commented pseudo fields Commented Jul 19, 2015 at 14:28
  • @charlietfl what's a commented pseudo fields ? Commented Jul 19, 2015 at 18:57

2 Answers 2

3

if I assume that your category table looks like this

+-----------+---------------------+------+-----+---------+-------+
| Field     | Type                | Null | Key | Default | Extra |
+-----------+---------------------+------+-----+---------+-------+
| id        | tinyint(4) unsigned | NO   | PRI | NULL    |       |
| parent_id | tinyint(4) unsigned | YES  | MUL | NULL    |       |
| name      | varchar(255)        | YES  |     | NULL    |       |
| note      | varchar(254)        | YES  |     | NULL    |       |
+-----------+---------------------+------+-----+---------+-------+

notice that you have a recursive relationship (parent_id pointing to id)

now, let's populate it with some data like this

+----+-----------+----------------+------+
| id | parent_id | name           | note |
+----+-----------+----------------+------+
|  1 | NULL      | bakery         | NULL |
|  2 |         1 | Cake           | NULL |
|  3 |         1 | Bun            | NULL |
|  4 |         1 | Toffee         | NULL |
|  5 |         1 | Bread          | NULL |
|  6 |         2 | Chocolate cake | NULL |
|  7 |         2 | Butter cake    | NULL |
|  8 |         3 | Honey bun      | NULL |
|  9 |         5 | Italian bread  | NULL |
| 10 |         5 | French bread   | NULL |
| 11 |         5 | Bereber bread  | NULL |
+----+-----------+----------------+------+

so now we create a method in the model that gets all the subcategories of a given id

Model

<?php
class menu_mdl extends CI_Model
{

        public function get_subcategories_id($id)
        {
            $qry_str = "SELECT
            categories.id,
            categories.`name` AS name
            FROM
            categories
            WHERE
            categories.parent_id = ".$id;
            $q = $this->db->query($qry_str);
            return $q->result();            
        }
}
?>

then we call this method in the controller menu.php as so

Controller

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class menu extends CI_Controller {


    public function index()
    {
        $this->load->model("menu_mdl");
         // get all the subcategories of the root category with id = 1
        $all_categories_id = $this->menu_mdl->get_subcategories_id(1);

        // prepare the menu as an HTML string  
        $menu = "<ul>";
        //loop through level1 then level2 then level3... you can go as many levels as you want!
        foreach($all_categories_id as $level1)
        {
            if($level1->id)
            {
                $menu .= "<li><a href='#'>".$level1->name."</a></li>"; 
                $sub_level1 = $this->menu_mdl->get_subcategories_id($level1->id);
                if ($sub_level1)
                {
                    $menu .= "<ul>";
                    foreach($sub_level1 as $level2)
                    {
                        $menu .= "<li><a href='#'>".$level2->name."</a></li>";
                        $sub_level2 = $this->menu_mdl->get_subcategories_id($level2->id);
                        if ($sub_level2)
                        {
                            $menu = "<ul>";
                            foreach($sub_level2 as $level3)
                            {
                                $menu .= "<li><a href='#'>".$level3->name."</a></li>";
                            }
                            $menu .= "</ul>";   
                        } 
                    }
                    $menu .= "</ul>";
                }
            }   

        }
        $menu .= "</ul>"; 

        $data["menu"] = $menu; // <--- this variable has all the menu as HTML string
        $this->load->view('menu',$data);
    }


}

now in the view we just echo the ready menu by a simple echo like that

view

<?php 
echo $menu ; 
?>

then the output will look like this

<ul>
        <li><a href='#'>Cake</a></li>
        <ul>
            <li><a href='#'>Chocolate cake</a></li>
            <li><a href='#'>Butter cake</a></li>
        </ul>
        <li><a href='#'>Bun</a></li>
        <ul>
            <li><a href='#'>Honey bun</a></li>
        </ul>
        <li><a href='#'>Toffee</a></li>
        <li><a href='#'>Bread</a></li>
        <ul>
            <li><a href='#'>Italian bread</a></li>
            <li><a href='#'>French bread</a></li>
            <li><a href='#'>Bereber bread</a></li>
        </ul>
    </ul>

that's all there is to it


update you can use this controller instead of the previous one, if you want (thanks to Meh for the idea about the recursive function) , to loop through all the subcategories until the last child using a function magix (because it's magic :p )

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class menu extends CI_Controller {


    public function index()
    {
        $this->load->model("menu_mdl");
         // get all the subcategories of the root category with id = 1
        $all_categories_id = $this->menu_mdl->get_subcategories_id(1);

        // prepare the menu as an HTML string  
        $menu = "<ul>";
        //loop through level1 then level2 then level3... you can go as many levels as you want!
        foreach($all_categories_id as $level1)
        {
            // loop until through subcategories until there is no subcategories 
            $this->magix($level1,$menu);
        }
        $menu .= "</ul>"; 

        $data["menu"] = $menu; // <--- this variable has all the menu as HTML string
        $this->load->view('menu',$data);
    }

    private function magix($level_id,&$menu)
    {
        if($level_id->id)
            {
                $menu .= "<li><a href='#'>".$level_id->name."</a></li>"; 
                $sub_level = $this->menu_mdl->get_subcategories_id($level_id->id);
                if ($sub_level)
                {
                    $menu .= "<ul>";
                    foreach($sub_level as $level2)
                    {
                        $menu .= "<li><a href='#'>".$level2->name."</a></li>";
                        $sub_level2 = $this->menu_mdl->get_subcategories_id($level2->id);
                        if ($sub_level2)
                        {
                            $this->magix($level_id,$menu);  
                        } 
                    }
                    $menu .= "</ul>";
                }
            }   
    }

}

I hope that helps

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

3 Comments

better to make a function to get subcategories and in that function say if it has sub, then call the same function to get subs. It makes an unlimited level category listing.
@meh yes that's what get_subcategories_id($id) does in the model and in the controller it just checks if there is a child and puts it in the $menu , or did I miss understood you ?
Look at toUL() function in my answer.
1

I share my own get_category() method. The idea is not mine. I got it from somewhere I don't remember about a year ago.

public static $list;
public static function get_category(){
        $map_result = Product::get_category_array();
        // it's like select * from categories. with your table structure

        foreach($map_result as $row){
            $ref = &$refs[$row['cat_id']];

            $ref['parent_id'] = $row['parent_id'];
            $ref['cat_name']  = $row['cat_name'];
            $ref['cat_id']  = $row['cat_id'];

            if ($row['parent_id'] == 0){
                $list[$row['cat_id']] = &$ref;
            }else{
                $refs[$row['parent_id']]['children'][$row['cat_id']] = &$ref;
            }
        }
        self::$list = $refs;

        function toUL($list){
            $class="";
            $html = "";

            foreach ($list as $value){
                if (!empty($value['children'])){
                    $html .= '<li><a class="dir" href="./index.php?cat='.$value['cat_id'].'">'.htmlspecialchars($value['cat_name'])."</a>";
                }else{
                    $html .= '<li><a href="./index.php?cat='.$value['cat_id'].'">'.htmlspecialchars($value['cat_name'])."</a>";
                }

                if (!empty($value['children'])){
                    $html .= "<ul>".toUL($value['children'])."</ul>";
                }
                $html .= "</li>";
            }
            return $html;
        }
        return toUL($list);
    }

Look at toUL function and how it's been used inside of it for a recursive listing.

3 Comments

that looks a bit complicated to me, how would I implement it with my solution , Im kinda scratching my head right now lol
@Baci The benefit of this code is that it uses 1 query to get categories then sort it in a recursive array then echo it. You can forget about the first part which is sorting in array. Just for outputting, take your first foreach() to a function forexample name it abc($id) then after if ($sub_level), use that abc($new_id) to get rest of categories and put it into a variable for echo. It might be a new solution but ur code works fine and it's just an improvement.
take a look :) I got inspired, using a recursive function like a man ! lol

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.