I can’t for the life of me convert my array to a nested UL LI tree, I’ve been attempting it all day but there must be some flaw that I cannot spot (probably because my array isn’t a very simple one).
Basically the array takes the form:
$array = array(
"0" => array(
"0" => array("letter" => "A", "data" => "123"),
"1" => array(
"0" => array(
"0" => array("letter" => "B", "data" => "123"),
"1" => array(
"0" => array(
"0" => array("letter" => "C", "data" => "123")
)
)
),
"1" => array(
"0" => array("letter" => "D", "data" => "123"),
"1" => array(
"0" => array(
"0" => array("letter" => "E", "data" => "123")
)
)
)
)
)
);
Explaining Array Above
The arrays come in pairs – the first number being the group, and the second being the row. The above has 3 columns (or levels as I call them) and there is only has one ‘group’.
So [0][0] would be group 0, first row, [0][1][0][0] would be the second row of level one, but is the first row of level 2, and so one.
Where basically I want the result to appear as follows (for the example above):
<ul id="mylist">
<li>
<ul class="initial">
<li>A</li>
<li class="top">
<ul class="wrap">
<li>
<ul class="inner">
<li>B</li>
<li class="top">
<ul class="wrap">
<li>
<ul class="inner">
<li>C</li>
</ul>
</li>
<li class="end"><a class="add">Add</a></li>
</ul>
</li>
</ul>
</li>
<li>
<ul class="inner">
<li>D</li>
<li class="top">
<ul class="wrap">
<li>
<ul class="inner">
<li>E</li>
</ul>
</li>
<li class="end"><a class="add">Add</a></li>
</ul>
</li>
</ul>
</li>
<li class="end"><a class="add">Add</a></li>
</ul>
</li>
</ul>
</li>
<li class="end"><a class="add">Add</a></li>
</ul>
Basically, an ‘add’ appears at the end of each node branch (last list item within ‘wrap’ class).
I’ve done the following so far, but I feel it isn’t correct at all, and doesn’t work correctly if additional nodes were added or nodes were removed.
function recursion($data, $level){
$skip = array_key_exists('data', $data[0]) ? 0 : 1;
if($skip == 0){
$level++;
if($level !== 1){
$out .= "<li>\n";
}
if($level == 1){
$out .= "<ul class='initial'>\n";
} else {
$out .= "<ul class='inner'>\n";
}
}
$count = 0;
$loop_count = 0;
$show_end = 0;
foreach($data as $key => $value){
$loop_count++;
if(is_array($value) && array_key_exists('data', $value)){
$count++;
$out .= ($skip == 0) ? "<li>" : "";
if($value['data'] == "123"){
$out .= $value['letter'];
}
if(!is_array($data[($key+1)][0])){
$out .= "</li>\n";
$out .= "<li class=\"end\"><a class=\"add\">Add</a></li>\n";
$out .= "</ul>\n";
$out .= "</li>\n";
$out .= "</ul>\n";
$out .= "</li>\n";
$out .= "<li class=\"end\"><a class=\"add\">Add</a></li>\n";
$show_end = 1;
}
$last_key = $key;
} else if(is_array($value)){
$out.= recursion($value, $level);
}
if($show_end == 1){
$out .= "</ul>\n";
}
if(is_array($value) && array_key_exists('data', $value) && !is_array($data[($key+1)])){
$out .= "</li>\n";
}
if($show_end == 1 && count($data) !== $count){
$out .= "<li>\n";
}
}
return $out;
}
Output of
print_r($array, true)
Array
(
[0] => Array
(
[0] => Array
(
[letter] => A
[data] => 123
)
[1] => Array
(
[0] => Array
(
[0] => Array
(
[0] => Array
(
[letter] => B
[data] => 123
)
[1] => Array
(
[0] => Array
(
[0] => Array
(
[letter] => C
[data] => 123
)
)
)
)
[1] => Array
(
[0] => Array
(
[letter] => D
[data] => 123
)
[1] => Array
(
[0] => Array
(
[0] => Array
(
[letter] => E
[data] => 123
)
)
)
)
)
)
)
)
Are you sure your array structure matches the HTML you have shown? I tweaked the array and came up with this function that seems to work.
Here are my changes to the array:
Then to call it: