My need is a very common select dropdown that displays hierarchical items where all child items are indented by adding
I have gotten up to populating a dropdown in php with the right hierarchical order, but can't get it to indent. How do I make the dropdown indent properly using the space trick, when items are showing in the correct order (children under the right parents), just not indented?
In Mysql I have a table with columns Category_ID Item_Name, and Parent_ID.
In php, using a query I fetch a self-referencing table that has columns Category and Parent
In php, using the fetched table of categories and immediate Parent Category, I call a function parseTree(); which takes the sql result array, and returns an array of the full tree structure.
In php I call a function printTree(); in between <select>
tags which recursively loops through the tree array and echos each node with <option>
tags.
Within printTree() is a function printChildren() whose purpose is to add indents to all children arrays if found. This does not work.
Desired Result:
<select>
<option>Root</option>
<option>Root</option>
<option> Child Level 1</option>
<option> Child Level 2</option>
<option> Child Level 3</option>
</select>
etc....
PHP
<?php
$sql = "SELECT
e.cat_Name AS 'Category',
m.cat_Name AS 'Parent Category'
FROM
categories_tbl e
lEFT JOIN
categories_tbl m ON m.cat_ID = e.parent_ID";
$result = mysqli_query($db, $sql);
function parseTree($tree, $root = "")
{
$return = array();
# Traverse the tree and search for direct children of the root
foreach($tree as $child => $parent) {
# A direct child is found
if($parent == $root) {
# Remove item from tree (we don't need to traverse this again)
unset($tree[$child]);
# Append the child into result array and parse its children
$return[] = array(
'name' => $child,
'children' => parseTree($tree, $child)
);
}
}
return empty($return) ? NULL : $return;
}
function printTree($tree)
{
$indent = "";
function printChildren($childrenarray)
{
$indent .= " ";
if(!is_null($childrenarray) && count($childrenarray) > 0) {
foreach($childrenarray as $node) {
echo '<option>' . $indent . $node['name'] . '</option>';
printChildren($node['children']);
}
}
}
if(!is_null($tree) && count($tree) > 0) {
foreach($tree as $node) {
echo '<option>' . $indentpaddingval . $node['name'] . '</option>';
if(!is_null($node['children']) && count($node['children']) > 0) {
printChildren($node['children']);
}
}
}
}
?>
HTML/PHP TO EXECUTE FUNCTIONS AND POPULATE SELECT
<select class="form-control">
<?php
$cat_tree_arr = array();
while ($row = mysqli_fetch_assoc($result)) {
$cat_tree_arr[$row['Category']] = $row['Parent Category'];
}
$result = parseTree($cat_tree_arr);
printTree($result);
?>
</select>
I'm adding the parsed Array containing the entire tree of categories in Parent/Children arrays here:
Array
(
[0] => Array
(
[name] => All Raw Materials
[children] => Array
(
[0] => Array
(
[name] => Bag Raw Materials
[children] => Array
(
[0] => Array
(
[name] => LDPE Materials
[children] =>
)
)
)
)
)
[1] => Array
(
[name] => All Finished Goods
[children] => Array
(
[0] => Array
(
[name] => Local Finished Goods
[children] => Array
(
[0] => Array
(
[name] => Local Bags
[children] =>
)
)
)
[1] => Array
(
[name] => Export Finished Goods
[children] => Array
(
[0] => Array
(
[name] => Export Bags
[children] =>
)
)
)
)
)
)
As per my understand, if categoryid is differentiate the all products then my answer will work for you.
There is no need to left join a same table again.