Skip to content

Instantly share code, notes, and snippets.

@mtvbrianking
Last active October 6, 2020 12:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mtvbrianking/d8883dabcadc177b8c7a5d586f96144b to your computer and use it in GitHub Desktop.
Save mtvbrianking/d8883dabcadc177b8c7a5d586f96144b to your computer and use it in GitHub Desktop.
Build nested tree from flat array.
<?php
$categories = [
['id' => 1, 'name' => 'TV & Home Theater', 'parent_id' => null,],
['id' => 2, 'name' => 'Tablets & E-Readers', 'parent_id' => null,],
['id' => 3, 'name' => 'Computers', 'parent_id' => null,],
['id' => 4, 'name' => 'Laptops', 'parent_id' => 3,],
['id' => 5, 'name' => 'PC Laptops', 'parent_id' => 4,],
['id' => 6, 'name' => 'Macbooks (Air/Pro)', 'parent_id' => 4,],
['id' => 7, 'name' => 'Desktops', 'parent_id' => 3,],
['id' => 8, 'name' => 'Monitors', 'parent_id' => 3,],
['id' => 9, 'name' => 'Cell Phones', 'parent_id' => null,],
];
// echo json_encode(['categories' => $categories]);
// ORDER BY categories.id ASC
/**
* @see https://stackoverflow.com/a/8587437/2732184 Source
*/
function buildTree(array $elements, $parent_id = null, $depth = 0) {
$tree = array();
foreach ($elements as $element) {
if ($element['parent_id'] == $parent_id) {
$element['depth'] = $depth;
$children = buildTree($elements, $element['id'], ($depth + 1));
if ($children) {
$element['children'] = $children;
}
$tree[] = $element;
}
}
return $tree;
}
$tree = buildTree($categories);
echo json_encode(['tree' => $tree]);
<?php
$categories = [
[
'id' => 1,
'name' => 'TV & Home Theater',
'parent_id' => null,
],
[
'id' => 2,
'name' => 'Tablets & E-Readers',
'parent_id' => null,
],
[
'id' => 3,
'name' => 'Computers',
'parent_id' => null,
'children' => [
[
'id' => 4,
'name' => 'Laptops',
'parent_id' => 3,
'children' => [
[
'id' => 5,
'name' => 'PC Laptops',
'parent_id' => 4,
],
[
'id' => 6,
'name' => 'Macbooks (Air/Pro)',
'parent_id' => 4,
],
]
],
[
'id' => 7,
'name' => 'Desktops',
'parent_id' => 3,
],
[
'id' => 8,
'name' => 'Monitors',
'parent_id' => 3,
],
]
],
[
'id' => 9,
'name' => 'Cell Phones',
'parent_id' => null,
],
];
function drawCategoriesTree(&$categories, $level = 0)
{
foreach ($categories as $category)
{
if (isset($category['children'])) {
echo sprintf("%s{$category['name']}", str_repeat('|--', $level)) . '<br/>';
$level++;
drawCategoriesTree($category['children'], $level);
} else {
echo sprintf("%s{$category['name']}", str_repeat('|--', $level)) . '<br/>';
$level++;
}
$level--;
}
}
drawCategoriesTree($categories);
/*
TV & Home Theater
Tablets & E-Readers
Computers
|--Laptops
|--|--PC Laptops
|--|--Macbooks (Air/Pro)
|--Desktops
|--Monitors
Cell Phones
*/
@mtvbrianking
Copy link
Author

mtvbrianking commented Jul 24, 2020

Print HTML nested list

function drawCategoriesTree(&$categories)
{
    $list = '<ul style="list-style: none; padding-left: 10px;">';
    foreach ($categories as $category)
    {    
        if (isset($category['children'])) {
            $list .= "<li>{$category['name']}</li>";
            $list .= drawCategoriesTree($category['children']);
        } else {
            $list .= "<li>{$category['name']}</li>";
        }
    }
    $list .= '</ul>';
    return $list;
}

@mtvbrianking
Copy link
Author

mtvbrianking commented Jul 24, 2020

Print HTML indented checkboxes

function drawCategoriesTree(&$categories)
{
    $list = '<ul style="list-style: none; padding-left: 10px;">';
    foreach ($categories as $category)
    {    
        if (isset($category['children'])) {
            $list .= "<li><input type='checkbox' value='{$category['id']}'><label>{$category['name']}</label></li>";
            $list .= drawCategoriesTree($category['children']);
        } else {
            $list .= "<li><input type='checkbox' value='{$category['id']}'><label>{$category['name']}</label></li>";
        }
    }
    $list .= '</ul>';
    return $list;
}

@mtvbrianking
Copy link
Author

mtvbrianking commented Jul 24, 2020

Print as indented select options

function drawCategoriesTree(&$categories, $level = 0)
{   
    $options = '';
    foreach ($categories as $category)
    {    
        if (isset($category['children'])) {
            $value = sprintf("%s{$category['name']}", str_repeat('&nbsp;&nbsp;', $level));
            $options .= "<option>{$value}</option>";
            $level++;
            $options .= drawCategoriesTree($category['children'], $level);
        } else {
            $value = sprintf("%s{$category['name']}", str_repeat('&nbsp;&nbsp;', $level));
            $options .= "<option>{$value}</option>";
            $level++;
        }
        $level--;
    }
    return $options;
}

echo '<select>' . drawCategoriesTree($categories) . '</select>';

@mtvbrianking
Copy link
Author

Print nested lists in Lavavel blade

Create a partial like; partials/project.blade.php

<li>{{ $project['name'] }}</li>
@if (count($project['children']) > 0)
    <ul>
    @foreach($project['children'] as $project)
        @include('partials.project', $project)
    @endforeach
    </ul>
@endif

Use in the main blade file like;

@if (count($projects) > 0)
    <ul>
    @foreach ($projects as $project)
        @include('partials.project', $project)
    @endforeach
    </ul>
@else
    @include('partials.projects-none')
@endif

Or;

@each('partials.project', $projects, 'project', 'partials.projects-none')

Source: Laravel Blade Recursive Partials with @each

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment