OK. I'll try to be clear as mud ...
I am learning php, css and javascript and I am having some problems...
I wrote the code below to generate a directory structure with the values returned by another php function.
For this example I forced some values in the roots array.
As it is, the code works very well, however, only with the three levels of depth. When adding a new level (child 2.2.2) we already have a problem (as expected the code shows "array" and does not create the new depth level, because there is no support implemented for more than three levels). My intention is to replace the if loop $counter_n != $last_n with something more "elegant" and allow the creation of new levels "dynamically", otherwise for each new level I need to include a new if loop.
In a second moment, I want to use javascript to be able to collapse the tree (changing the parentOpen class by parentClosed).
Note: I know of jstree's existence and it was from him that I "stole" the image sprite, but I'm reinventing the wheel just so I can learn ...
Note2: the 32px.png (edited to my needs) can be found at https://i.stack.imgur.com/ttnQ9.jpg
Eager for answers.
Grateful,
css:
ul
{
list-style-type: none;
text-decoration: none;
}
.flex-container
{
padding: 0;
margin: 0;
list-style: none;
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-flex-flow: row wrap;
align-items: center;
justify-content: flex-start;
}
.flex-item
{
width:32px;
height:32px;
position: absolute;
color: white;
font-weight: bold;
font-size: 3em;
text-align: center;
content:"";
display:block;
position:relative;
background-image: url(32px.png);
background-repeat:no-repeat;
overflow:hidden;
background-position: -0px -32px;
}
.line
{
background-position: -0px -0px;
}
.child
{
background-position: -32px -0px;
}
.lastChild
{
background-position: -32px -32px;
}
.parentClosed
{
background-position: -64px -0px;
}
.parentOpen
{
background-position: -96px -0px;
}
.lastParentClosed
{
background-position: -64px -32px;
}
.lastParentOpen
{
background-position: -96px -32px;
}
.checkBoxClear
{
background-position: -128px -0px;
}
.checkBoxPartial
{
background-position: -160px -0px;
}
.checkBoxChecked
{
background-position: -192px -0px;
}
.icon1
{
background-position: -128px -32px;
margin-left: -12px;
}
.icon2
{
background-position: -160px -32px;
margin-left: -12px;
}
.icon3
{
background-position: -192px -32px;
margin-left: -12px;
}
php
$parents1 = array("parent1.1"=>array("1.1.1", "1.1.2"), "parent1.2"=>array("1.2.1"));
$parents2 = array("parent2.1"=>array("2.1.1", "2.1.2"), "parent2.2"=>array("2.2.1", "2.2.2"=>array("2.2.2.1", "2.2.2.2"), "2.2.3"), "parent2.3"=>array("2.3.1", "2.3.2"));
$parents3 = array("parent3.1"=>array("3.1.1"));
$roots = array("root1"=>$parents1, "root2"=>$parents2, "root3"=>$parents3);
echo '<div><ul>';
$last_a = count($roots);
$counter_a = 1;
foreach ($roots as $root => $parent)
{
echo '<li class="flex-container">';
if ($counter_a != $last_a)
echo '<div class="flex-item parentOpen"></div>';
else
echo '<div class="flex-item lastParentOpen"></div>';
echo '<div class="flex-item checkBoxClear"></div><div class="flex-item icon3"></div><div class="flex-text">'
.$root
.'</div></li>';
$last_b = count($parent);
$counter_b = 1;
foreach ($parent as $name => $children)
{
echo '<li class="flex-container">';
if ($counter_a != $last_a)
echo '<div class="flex-item line"></div>';
else
echo '<div class="flex-item"></div>';
if ($counter_b != $last_b)
echo '<div class="flex-item parentOpen"></div>';
else
echo '<div class="flex-item lastParentOpen"></div>';
echo '<div class="flex-item checkBoxClear"></div><div class="flex-text">'.$name.'</div></li>';
$last_c = count($children);
$counter_c = 1;
foreach ($children as $key => $value)
{
echo '<li class="flex-container">';
if ($counter_a != $last_a)
echo '<div class="flex-item line"></div>';
else
echo '<div class="flex-item"></div>';
if ($counter_b != $last_b)
echo '<div class="flex-item line"></div>';
else
echo '<div class="flex-item"></div>';
if ($counter_c != $last_c)
echo '<div class="flex-item child"></div>';
else
echo '<div class="flex-item lastChild"></div>';
echo '<div class="flex-item checkBoxClear"></div><div class="flex-item icon2"></div><div class="flex-text">'.$value.'</div></li>';
$counter_c++;
}
$counter_b++;
}
$counter_a++;
}
echo '</ul></div>';
Using the answer of @martindilling I was able to improve my code. Follow new php code: /* * An item in the tree. Have a name and can have a parent and children. */ class Item { public $name = ''; public $parent = null; public $children = [];
public function __construct($name)
{
$this->name = $name;
}
public function addChild(Item $child)
{
$this->parent = $this;
$this->children[] = $child;
}
}
/*
* Build our tree.
* Should be possible to make a function that takes a simple array
* and builds this from that.
*/
$roots = array("root1"=>array("parent1.1"=>array("1.1.1", "1.1.2"), "parent1.2"=>array("1.2.1")), "root2"=>array("parent2.1"=>array("2.1.1", "2.1.2"), "parent2.2"=>array("2.2.1", "2.2.2"=>array("2.2.2.1"), "2.2.3"), "parent2.3"=>array("2.3.1", "2.3.2")), "root3"=>array("parent3.1"=>array("3.1.1"=>array("3.1.1.1", "3.1.1.2"=>array("3.1.1.2.1", "3.1.1.2.2", "3.1.1.2.3", "3.1.1.2.4")))));
/*
* Our recursive function to create the html for our tree.
*/
function buildTreeHtml(Item $item, $level) {
if ($level!=0)
{
if ($level==1)
$out = '<div class="flex-item checkBoxClear"></div><div class="flex-item icon3"></div>';
else
$out = '<div class="flex-item checkBoxClear"></div><div class="flex-item icon2"></div>';
$out .= '<div class="flex-text">'.$item->name.'</div></li>';
}
if (!empty($item->children))
{
$last_a1 = count($item->children);
$counter_a1 = 1;
foreach ($item->children as $child)
{
$out .= '<li class="flex-container">';
for ($cnt = 0; $cnt < $level; $cnt++)
{
$out .='<div class="flex-item line"></div>';
}
if ($counter_a1 != $last_a1)
$out .= '<div class="flex-item child"></div>';
else
$out .= '<div class="flex-item lastChild"></div>';
$out .= buildTreeHtml($child, $level+1);
$counter_a1++;
}
}
return $out;
}
/*
* Build the Item object hierarchy from an array.
*/
function buildTree2($root, array $array) {
$root = new Item($root);
foreach ($array as $key => $value) {
if (!is_array($value)) {
$key = $value;
$value = [];
}
$root->addChild(buildTree2($key, $value));
}
return $root;
}
/*
* Do the building and printing the html.
*/
$root2 = buildTree2(null, $roots);
echo buildTreeHtml($root2);
Here is the image of the final result, the new problem (the highlighted lines should not exist) and how it should be... result
If anyone still has an interest in helping, I'll appreciate it.
Grateful,