Reputation: 873
I want to to display the list of category in a table and the sub category of each parent category right under.
EDIT
I want it look like this:
Category One
-> Sub category One #1
-> Sub category One #2
Category Two
-> Sub category Two #1
-> Sub category Two #2
Category Three
-> Sub category Three #1
-> Sub category Three #2
But what I got is:
Category One
Category Two
Category Three
-> Sub category One #1
-> Sub category One #2
-> Sub category Two #1 ... etc
Here is the model:
function get_categories() {
$data = array();
$this->db->group_by('parent_id,category_id');
$query = $this->db->get('category');
if ($query->num_rows() > 0) {
foreach ($query->result() as $row) {
$data[] = $row;
}
}
return $data;
}
And in the controller I call this function with $data['categories']=$this->category_model->get_categories()
. And I display the data in the view with this code:
<?php foreach ($categories as $cat) : ?>
<tr>
<td><?php echo $cat->name ?></td>
<td><?php echo $cat->description ?></td>
</tr>
<?php endforeach; ?>
But the problem is, instead of under each their parent category, the sub categories are all showing on the bottom of the list. Please help me to fix this problem. Thanks.
Upvotes: 2
Views: 6458
Reputation: 1
In Model
//categories
public function getCategories()
{
$query = $this->db->query('select * from categories where cat_parent=0');
return $query->result_array();
}
public function getCategoriesSub($parent)
{
$query = $this->db->query("select * from categories where cat_parent='$parent'");
return $query->result_array();
}
in Controller
public function categories()
{
$data['mcats'] = $this->admin_model->getCategories();
foreach($data['mcats'] as $key =>$val){
$subcats = $this->admin_model->getCategoriesSub($val['cid']);
if($subcats){
$data['scats'][$val['cid']] = $subcats;
}
}
$this->load->view('admin/header');
$this->load->view('admin/category_list', $data);
$this->load->view('admin/footer');
}
in View
<ul>
<?php
foreach ($mcats as $key =>$val)
{
?>
<li><?php echo $val['cat_name']; ?>
<ul>
<?php
foreach ($scats[$val['cid']] as $sub) {
echo '<li>' . $sub['cat_name'] . '</li>';
}
?>
</ul>
</li>
<?php
}
?>
</ul>
its working code. try this
Upvotes: 0
Reputation: 2995
You need iterate your categories and group them by parent id. As i understand your categories are stored as Adjacency List
, so maybe this example will be helpfull:
function get_categories(){
$this->db->order_by('parent_id');
return $this->db->get('category')->result_array();
}
$categories = get_categories();
$result = array();
foreach($categories as $cat){
if($cat['parent_id'] && array_key_exists($cat['parent_id'], $result)){
$result[$cat['parent_id']]['sub_categories'][] = $cat;
}
else{
$result[$cat['id']] = $cat;
}
}
Second step need to render html:
<?php foreach ($result as $cat):?>
<tr>
<td><?=$cat['name'];?></td>
<td><?=$cat['description'];?></td>
</tr>
<?php if(isset($cat['sub_categories'])):?>
<?php foreach($cat['sub_categories'] as $sub_category):?>
<tr>
<td><?=$sub_category['name'];?></td>
<td><?=$sub_category['description'];?></td>
</tr>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
Html output is very similar to @scrowler
answer.
Upvotes: 2
Reputation: 24406
So you're retrieving all the categories correctly, but they aren't displaying correctly. Your problem is that you're looping through all the categories and you aren't correctly outputting the relevant sub categories to the parents. I don't know what your data structure is like, but you must have a foreign key type field somewhere that you can check.
Here's an example of how it should work:
<?php foreach ($categories as $cat) : ?>
<tr>
<td><?php echo $cat->name ?></td>
<td><?php echo $cat->description ?></td>
</tr>
<?php foreach($sub_categories as $sub_category) : ?>
<?php
// if this sub_category doesn't belong to the current parent, skip it
if($sub_category['parent_id'] != $cat['category_id'])
continue;
?>
<tr>
<td><?php echo $sub_category->name ?></td>
<td><?php echo $sub_category->description ?></td>
</tr>
<?php endforeach; ?>
<?php endforeach; ?>
Of course, the better way to do this would be to obtain your data in the correct structure to begin with, e.g. nested array Parent => array(parent_data, Children => array(children_data))
.
Upvotes: 2