Reputation: 1844
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
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
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(' ', $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