Bitte zum Testen nur aktuelle Browser verwenden! ILIAS unterstützt alle aktuellen Browser wie z.B. Firefox, Safari, Microsoft Edge, Chrome und Chromium. Der von Micosoft nicht mehr unterstützte und weiterentwickelte 'Internet Explorer' kann nicht zum Testen von ILIAS 7 verwendet werden.
Testers are the best!

Documentation

Kitchen Sink documentation of style: 'Delos' of skin: 'ILIAS'

Expandable

Description

Purpose
An Expandable Tree focusses on the exploration of hierarchically structured data. Its nodes can be expanded to reveal the underlying nodes; nodes in the Expandable Tree can also be closed to hide all underlying nodes. This lets the user decide on the simultaneously shown levels of the data's hierarchy.
Composition
A Tree is composed of Nodes. Further levels (sub-Nodes) are indicated by an Expand Glyph for the closed state of the Node and respectively by a Collapse Glyph for the expanded state. If there are no sub-Nodes, no Glyph will be shown at all. It is possible to only render a part of a tree and load further parts on demand.
Effect
When clicking a Node, it will expand or collapse, thus showing or hiding its sub-Nodes.

Rules

Usage
  1. Expandable Trees SHOULD only be used when there is a reasonably (large) amount of entries.
  2. Expandable Trees SHOULD NOT be used to display several aspects of one topic/item, like it would be the case when e.g. listing a repository object and its properties as individual nodes.
Accessibility
  1. Expandable Trees MUST bear the ARIA role "tree".
  2. The "aria-label" attribute MUST be set for Expandable Trees.
  3. The "aria-label" attribute MUST be language-dependant.
  4. The "aria-label" attribute MUST describe the content of the Tree as precisely as possible. "Tree" MUST NOT be set as label, labels like "Forum Posts" or "Mail Folders" are much more helpful. (Note that "Tree" is already set by the ARIA role attribute.)
  5. Every Node in der Tree MUST be accessible by keyboard. Note they this does not imply, that all Nodes are tabbable.
  6. At least Node in the tree MUST be tabbable.

Example 1: Expandable2

declare(strict_types=1);
 
class DataNode
{
    /**
     * @var string
     */
    protected $label = "";
 
    /**
     * @var array
     */
    protected $children = [];
 
    public function __construct(string $label, array $children = [])
    {
        $this->label = $label;
        $this->children = $children;
    }
    public function getLabel()
    {
        return $this->label;
    }
    public function getChildren()
    {
        return $this->children;
    }
}
 
function expandable2()
{
    global $DIC;
    $f = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
 
 
    $n11 = new DataNode('1.1');
    $n12 = new DataNode('1.2', array(new DataNode('1.2.1')));
    $n1 = new DataNode('1', [$n11, $n12]);
    $data = [$n1];
 
    $recursion = new class implements \ILIAS\UI\Component\Tree\TreeRecursion {
        public function getChildren($record, $environment = null) : array
        {
            return $record->getChildren();
        }
 
        public function build(
            \ILIAS\UI\Component\Tree\Node\Factory $factory,
            $record,
            $environment = null
        ) : \ILIAS\UI\Component\Tree\Node\Node {
            return $factory->simple($record->getLabel());
        }
    };
 
    $tree = $f->tree()->expandable("Label", $recursion)
        ->withData($data);
 
    return $renderer->render($tree);
}
 

Example 2: Expandable async repo

 
if ($_GET['async_ref']) {
    $ref = (int) $_GET['async_ref'];
    expandable_async_repo($ref);
    exit();
}
 
function expandable_async_repo($ref = null)
{
    global $DIC;
    $ilTree = $DIC['tree'];
 
    if (is_null($ref)) {
        $do_async = false;
        $ref = 1;
        $data = array(
            $ilTree->getNodeData(1)
        );
    } else {
        $do_async = true;
        $data = $ilTree->getChilds($ref);
        if (count($data) === 0) {
            return;
        }
    }
 
    $recursion = new class implements \ILIAS\UI\Component\Tree\TreeRecursion {
        public function getChildren($record, $environment = null) : array
        {
            return [];
        }
 
        public function build(
            \ILIAS\UI\Component\Tree\Node\Factory $factory,
            $record,
            $environment = null
        ) : \ILIAS\UI\Component\Tree\Node\Node {
            $ref_id = $record['ref_id'];
            $label = $record['title']
                . ' (' . $record['type'] . ', ' . $ref_id . ')';
 
            $icon = $environment['icon_factory']->standard($record["type"], '');
            $url = $this->getAsyncURL($environment, $ref_id);
 
            $node = $factory->simple($label, $icon)
                ->withAsyncURL($url);
 
            //find these under ILIAS->Administration in the example tree
            if ((int) $ref_id > 9 && (int) $ref_id < 20) {
                $label = $environment['modal']->getShowSignal()->getId();
                $node = $factory->simple($label)
                    ->withAsyncURL($url)
                    ->withOnClick($environment['modal']->getShowSignal());
            }
 
            return $node;
        }
 
        protected function getAsyncURL($environment, string $ref_id) : string
        {
            $url = $environment['url'];
            $base = substr($url, 0, strpos($url, '?') + 1);
            $query = parse_url($url, PHP_URL_QUERY);
            parse_str($query, $params);
            $params['async_ref'] = $ref_id;
            $url = $base . http_build_query($params);
            return $url;
        }
    };
 
    $f = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
    $image = $f->image()->responsive("src/UI/examples/Image/mountains.jpg", "Image source: https://stocksnap.io, Creative Commons CC0 license");
    $page = $f->modal()->lightboxImagePage($image, 'Mountains');
    $modal = $f->modal()->lightbox($page);
 
    $environment = [
        'url' => $DIC->http()->request()->getRequestTarget(),
        'modal' => $modal,
        'icon_factory' => $f->symbol()->icon()
    ];
 
    $tree = $f->tree()->expandable("Label", $recursion)
        ->withEnvironment($environment)
        ->withData($data);
 
    if (!$do_async) {
        return $renderer->render([$modal, $tree]);
    } else {
        echo $renderer->renderAsync([$modal, $tree->withIsSubTree(true)]);
    }
}
 

Example 3: Expandable

function expandable()
{
    global $DIC;
    $f = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
 
    $data = [
        ['label' => 'root', 'children' => [
            ['label' => '1', 'children' => [
                ['label' => '1.1', 'children' => [
                    ['label' => '1.1.1', 'children' => []],
                    ['label' => '1.1.2', 'children' => []]
                ]],
                ['label' => '1.2', 'children' => []],
                ['label' => '1.3', 'children' => []]
            ]],
            ['label' => '2', 'children' => [
                ['label' => '2.1', 'children' => []],
            ]],
            ['label' => '3', 'children' => [
                ['label' => '3.1', 'children' => [
                    ['label' => '3.1.1', 'children' => [
                        ['label' => '3.1.1.1', 'children' => []],
                    ]],
                ]],
 
            ]],
        ]]
    ];
 
    $recursion = new class implements \ILIAS\UI\Component\Tree\TreeRecursion {
        public function getChildren($record, $environment = null) : array
        {
            return $record['children'];
        }
 
        public function build(
            \ILIAS\UI\Component\Tree\Node\Factory $factory,
            $record,
            $environment = null
        ) : \ILIAS\UI\Component\Tree\Node\Node {
            $label = $record['label'];
            $node = $factory->simple($label);
 
            if (count($record['children']) === 0) {
                $node = $node->withOnClick($environment['modal']->getShowSignal());
            }
 
            if ($label === "root" || $label === "2") {
                $node = $node->withExpanded(true);
            }
            if ($label === "2") {
                $node = $node->withHighlighted(true);
            }
 
            return $node;
        }
    };
 
    $image = $f->image()->responsive("src/UI/examples/Image/mountains.jpg", "Image source: https://stocksnap.io, Creative Commons CC0 license");
    $page = $f->modal()->lightboxImagePage($image, 'Mountains');
    $modal = $f->modal()->lightbox($page);
    $environment = [
        'modal' => $modal
    ];
 
    $tree = $f->tree()->expandable("Label", $recursion)
        ->withEnvironment($environment)
        ->withData($data)
        ->withHighlightOnNodeClick(true);
 
    return $renderer->render([
        $modal,
        $tree
    ]);
}
 

Relations

Parents
  1. UIComponent
  2. Tree