Pink Code
Pink Code

Reputation: 1844

print multilevel child parent categories into optgroup and selectbox

i have this category MySql table:

id , name , parent

Now with this function i list categories in selectbox and optgroup html tags:

$options    = array();
$categories = DataAccess::fetch("
  SELECT 
    * , p.name AS parent 
  FROM 
    cats AS child
  INNER JOIN
    cats AS p ON p.id = child.parent
");
foreach($categories as $category){
  $parent = $category['parent'];
  if (! isset($options[$parent])) $options[$parent] = array();
  $options[$parent][$category['id']] = $category['name'];
}
echo '<select>';
$selid = 13;
foreach($options as $group => $option) {
  printf('<optgroup label="%s">', $group);
  foreach ($option as $id => $label) {
   $selcat = ($selid == $id) ? 'selected' : '';
    printf('<option %s value="%s">%s</option>',$selcat, $id, $label);

  }
  printf('</optgroup>');
}
echo "</select>";

This function ouhput worked for One child parent categories and output is:

<select class="selectpicker" >
   <optgroup label="News">
     <option selected value="13">War</option>
   </optgroup>
   <optgroup label="article">
     <option selected value="14">tech</option>
   </optgroup>
</select>

Now, I have Three problem:

1- if i create many child This function notwork and print only One Child. i need to Like This:

News
--Sport
--War
--tech
Article
--tech
--php
--linux

2 - in need to print Multilevel categories with optgroup Like This:

News
--Sport
----Sky
----Football
------Football-1
--War
----War1
--tech
Article
--tech
----tech2
------tech3
--php
--linux

3 - Not Print categories if parent = 0 (root), This print only categories with child parent.

how do fix/print this?

Upvotes: 3

Views: 1873

Answers (1)

Sergiu Paraschiv
Sergiu Paraschiv

Reputation: 10163

You can't. select and optgroup don't support multiple levels although standard says they should. You'll have to manually left pad your options with &nbsp; according to their level. Normal spaces don't work.

You don't seem to have implemented this multilevel tree yet. I'd start by reading the answers on this question.

Then I'd write a simple recursive function like this:

function walkTree($nodes, $level = 0) {
    foreach($nodes as $node) {
        echo '<option>' . str_repeat('&nbsp;', $level) . $node->label . '</option>';
        if($node->children) {
            walkTree($node->children, $level + 1); 
        }
    }
}

walkTree($root->children);

This assumes you have an object hierarchy, but it's not necessary. You can use your existing database and write a function that returns all child nodes of another node:

function getChildren($id) {
    $categories = DataAccess::fetch("
      SELECT 
        *
      FROM 
        cats
      WHERE 
        cats.parent = $id
    ");

    return $categories;
}

Then you'd need to get the initial list of root nodes (WHERE cats.parent IS NULL maybe?) and pass it to walkTree, where $node->children is replaced by getChildren($node->id).

Obviously this means a lot of querying. You either need to switch to a nested set hierarchy or something similar, or maybe cache the resulting HTML.

Upvotes: 2

Related Questions