Reputation: 41
I'm building navigation for a site. I have all my data stored on online JSON, here's an example:
{
"State": 0,
"Tasks": [
{
"Id": 1000000,
"ParentId": 0,
"TaskCode": "1 ",
"Name": "item 1",
"Description": "item 1",
"Url": "",
"Parameter": ""
},
{
"Id": 1010000,
"ParentId": 1000000,
"TaskCode": "1.1 ",
"Name": "item 1.1",
"Description": "item 1.1",
"Url": "",
"Parameter": ""
},
{
"Id": 1010100,
"ParentId": 1010000,
"TaskCode": "1.1.1 ",
"Name": "item 1.1.1",
"Description": "item 1.1.1",
"Url": "",
"Parameter": ""
},
{
"Id": 1010200,
"ParentId": 1010000,
"TaskCode": "1.1.2 ",
"Name": "item 1.1.2",
"Description": "item 1.1.2",
"Url": "",
"Parameter": ""
},
{
"Id": 1010300,
"ParentId": 1010000,
"TaskCode": "1.1.3 ",
"Name": "item 1.1.3",
"Description": "item 1.1.3",
"Url": "",
"Parameter": ""
},
{
"Id": 1010400,
"ParentId": 1010000,
"TaskCode": "1.1.4 ",
"Name": "item 1.1.4",
"Description": "item 1.1.4",
"Url": "",
"Parameter": ""
},
{
"Id": 1020000,
"ParentId": 1000000,
"TaskCode": "1.2 ",
"Name": "item 1.2",
"Description": "item 1.2",
"Url": "",
"Parameter": ""
},
{
"Id": 1030000,
"ParentId": 1000000,
"TaskCode": "1.3 ",
"Name": "item 1.3",
"Description": "item 1.3",
"Url": "",
"Parameter": ""
}
]
}
and then i create a function like this:
function buildNavigation($items, $parent = '0')
{
$hasChildren = false;
$outputHtml = '<ul>%s</ul>';
$childrenHtml = '';
foreach($items as $item)
{
$curr_parent = $item->Id;
if ($item->ParentId == $parent) {
$hasChildren = true;
$childrenHtml .= "<li>";
$childrenHtml .= "<a href='" . $item->Url . "'><img alt='' src='xxx.png'>";
$childrenHtml .= trim($item->TaskCode).". " . $item->Name . "</a>";
foreach($items as $child)
{
$cur_node = $child->Id;
if ($child->ParentId == $curr_parent) {
$hasChildren = true;
$childrenHtml .= '<ul>';
$childrenHtml .= '<li>';
$childrenHtml .= '<a href="' . $child->Url . '">';
$childrenHtml .= trim($child->TaskCode) . ". " . $child->Name . "</a>";
foreach($items as $child2)
{
$cur_node2 = $child2->Id;
if ($child2->ParentId == $cur_node) {
$hasChildren = true;
$childrenHtml .= '<ul>';
$childrenHtml .= '<li>';
$childrenHtml .= '<a href="' . $child2->Url . '">';
$childrenHtml .= trim($child2->TaskCode).". " . $child2->Name . "</a>";
$childrenHtml .= '</li>';
$childrenHtml .= '</ul>';
}
}
$childrenHtml .= '</li>';
$childrenHtml .= '</ul>';
}
}
$childrenHtml .= '</li>';
}
}
// Without children, we do not need the <ul> tag.
if (!$hasChildren) {
$outputHtml = '';
}
// Returns the HTML
return sprintf($outputHtml, $childrenHtml);
}
echo buildNavigation($json_data->Tasks);
but what i got on html was like this:
<ul>
<li>
<a href=''><img alt='' src='xxx.png'>1. item 1</a>
<ul>
<li>
<a href="">1.1. item 1.1</a>
<ul>
<li><a href="">1.1.1. item 1.1.1</a></li>
</ul>
<ul>
<li><a href="">1.1.2. item1.1.2</a></li>
</ul>
<ul>
<li><a href="">1.1.3. item1.1.3</a></li>
</ul>
<ul>
<li><a href="">1.1.4. item1.1.4</a></li>
</ul>
<!-- .... (and more) -->
there's should be like:
<ul>
<li>
<a href=''><img alt='' src='xxx.png'>1. item1</a>
<ul>
<li>
<a href="">1.1. item1.1</a>
<ul>
<li><a href="">1.1.1. item1.1.1</a></li>
<li><a href="">1.1.2. item1.1.2</a></li>
<li><a href="">1.1.3. item1.1.3</a></li>
<li><a href="">1.1.4. item1.1.4</a></li>
</ul>
</li>
</ul>
</li>
</ul>
can anybody help improve my PHP function?
Thanks.
Upvotes: 1
Views: 1201
Reputation: 95121
This is what i think your code should look like
$json = json_decode($json);
echo buildNavigation($json->Tasks);
Output
<ul>
<li><a href="">1. Pelayanan Pelanggan</a>
<ul>
<li><a href="">1.1. Sambung Baru</a>
<ul>
<li><a href="">1.1.1. Pendaftaran</a></li>
<li><a href="">1.1.2. Survey</a></li>
<li><a href="">1.1.3. BA Survey</a></li>
<li><a href="">1.1.4. SPK Penyambungan</a></li>
</ul></li>
<li><a href="">1.2. Koreksi Tarif</a></li>
<li><a href="">1.3. Pemutusan Sambungan Atas Permintaan Pelanggan</a></li>
</ul></li>
</ul>
Function Used
function buildNavigation($items, $parent = '0') {
$next = function ($items, $parent) {
return array_filter($items, function ($v) use($parent) {
return $v->ParentId == $parent;
});
};
$output = "<ul>";
foreach ( $next($items, $parent) as $item ) {
$output .= '<li>';
$output .= sprintf('<a href="%s">%s. %s</a>', $item->Url, trim($item->TaskCode), $item->Name);
if ($next($items, $item->Id)) {
$output .= buildNavigation($items, $item->Id);
}
$output .= '</li>';
}
$output .= "</ul>";
return $output;
}
Upvotes: 4
Reputation: 877
Try this, hope it will work for u
function buildNavigation($items, $parent = '0')
{
$hasChildren = false;
$outputHtml = '<ul>%s</ul>';
$childrenHtml = '';
foreach($items as $item)
{
$curr_parent = $item->Id;
if ($item->ParentId == $parent) {
$hasChildren = true;
$childrenHtml .= "<li>";
$childrenHtml .= "<a href='" . $item->Url . "'><img alt='' src='xxx.png'>";
$childrenHtml .= trim($item->TaskCode).". " . $item->Name . "</a>";
$childrenHtml .= '<ul>';
foreach($items as $child)
{
$cur_node = $child->Id;
if ($child->ParentId == $curr_parent) {
$hasChildren = true;
$childrenHtml .= '<li>';
$childrenHtml .= '<a href="' . $child->Url . '">';
$childrenHtml .= trim($child->TaskCode) . ". " . $child->Name . "</a>";
$childrenHtml .= '<ul>';
foreach($items as $child2)
{
$cur_node2 = $child2->Id;
if ($child2->ParentId == $cur_node) {
$hasChildren = true;
$childrenHtml .= '<li>';
$childrenHtml .= '<a href="' . $child2->Url . '">';
$childrenHtml .= trim($child2->TaskCode).". " . $child2->Name . "</a>";
$childrenHtml .= '</li>';
}
}
$childrenHtml .= '</ul>';
$childrenHtml .= '</li>';
}
}
$childrenHtml .= '</ul>';
$childrenHtml .= '</li>';
}
}
// Without children, we do not need the <ul> tag.
if (!$hasChildren) {
$outputHtml = '';
}
// Returns the HTML
return sprintf($outputHtml, $childrenHtml);
}
echo buildNavigation($json_data->Tasks);
Upvotes: 2