UPDATE-RATE

Die Test-Installation wird aktuell zwischen 8:00 und 18:00 Uhr stündlich zur vollen Stunde aktualisiert.

Alles neu macht der Mai

ILIAS 9 ist da! Alle Infos zu den Highlights der neuen Version gibt es hier!

Documentation

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

Standard

Description

Purpose
Standard Popovers are used to display other components. Whenever you want to use the standard-popover, please hand in a PullRequest and discuss it.
Composition
The content of a Standard Popover displays the components together with an optional title.

Rules

Usage
  1. Standard Popovers MUST NOT be used to render lists, use a Listing Popover for this purpose.
  2. Standard Popovers SHOULD NOT contain complex or large components.
  3. Usages of Standard Popovers MUST be accepted by JourFixe.
  4. Popovers with fixed Position MUST only be attached to triggerers with fixed position.

Example 1: Show card in popover

<?php
 
declare(strict_types=1);
 
namespace ILIAS\UI\examples\Popover\Standard;
 
function show_card_in_popover()
{
    global $DIC;
 
    // This example shows how to render a card containing an image and a descriptive list inside a popover.
    $factory = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
 
    $image = $factory->image()->responsive("./templates/default/images/logo/HeaderIcon.svg", "Thumbnail Example");
    $card = $factory->card()->standard("Title", $image)->withSections(array($factory->legacy("Hello World, I'm a card")));
    $popover = $factory->popover()->standard($card)->withTitle('Card');
    $button = $factory->button()->standard('Show Card', '#')
        ->withOnClick($popover->getShowSignal());
 
    return $renderer->render([$popover, $button]);
}
 

Example 2: Show popover with async loaded content

<?php
 
declare(strict_types=1);
 
namespace ILIAS\UI\examples\Popover\Standard;
 
function show_popover_with_async_loaded_content()
{
    global $DIC;
    $factory = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
    $refinery = $DIC->refinery();
    $request_wrapper = $DIC->http()->wrapper()->query();
 
    if (
        $request_wrapper->has('renderPopoverAsync') &&
        $request_wrapper->retrieve('renderPopoverAsync', $refinery->kindlyTo()->bool())
    ) {
        // This is the ajax request to load the content of the popover. During the ajax request,
        // a loading spinner is presented to the user. Check the code below on how to construct the popover,
        // e.g. using Popover::withAsyncContentUrl().
        $content = $factory->legacy('This text is rendered async');
        echo $renderer->render($content);
        exit();
    }
 
    $async_url = $_SERVER['REQUEST_URI'] . '&renderPopoverAsync=1';
    $popover = $factory->popover()->standard($factory->legacy(''))
        ->withTitle('Popover')
        ->withAsyncContentUrl($async_url);
    $button = $factory->button()->standard('Show Popover', '#')
        ->withOnClick($popover->getShowSignal());
 
    return $renderer->render([$popover, $button]);
}
 

Example 3: Show popover with different positions

<?php
 
declare(strict_types=1);
 
namespace ILIAS\UI\examples\Popover\Standard;
 
function show_popover_with_different_positions()
{
    global $DIC;
    $factory = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
 
    $content = $factory->legacy('The position of this popover is calculated automatically based on the available space. Note that the max width CSS setting is used here, as this text is quite long.');
    $popover = $factory->popover()->standard($content);
    $button = $factory->button()->standard('Auto Popover', '#')
        ->withOnClick($popover->getShowSignal());
 
    $content = $factory->legacy('The position of this popover is either on top or bottom of the triggerer, based on the available space');
    $popover2 = $factory->popover()->standard($content)
        ->withVerticalPosition();
    $button2 = $factory->button()->standard('Vertical Popover', '#')
        ->withOnClick($popover2->getShowSignal());
 
    $content = $factory->legacy('The position of this popover is either on the left or right of the triggerer, based on the available space');
    $popover3 = $factory->popover()->standard($content)
        ->withHorizontalPosition();
    $button3 = $factory->button()->standard('Horizontal Popover', '#')
        ->withOnClick($popover3->getShowSignal());
 
    $buttons = implode(' ', [$renderer->render($button), $renderer->render($button2), $renderer->render($button3)]);
 
    return $buttons . $renderer->render([$popover, $popover2, $popover3]);
}
 

Example 4: Show popover with dynamic changing content

<?php
 
declare(strict_types=1);
 
namespace ILIAS\UI\Examples\Popover\Standard;
 
use ILIAS\UI\Implementation\Component\ReplaceContentSignal;
 
function show_popover_with_dynamic_changing_content()
{
    global $DIC;
    $factory = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
    $refinery = $DIC->refinery();
    $request_wrapper = $DIC->http()->wrapper()->query();
 
    // This example shows how to change the content of a popover dynamically with ajax requests.
    // Each popover offers a signal to replace its content, similar to the show signal which shows the popover.
    // The replace signal will load the new content via ajax from a given URL and insert it into the popover.
 
    // The popover in this example initially shows three buttons. Each button will replace the content
    // of the popover with a new "page" showing some text. Each page also contains a back button which
    // again replaces the content of the popover with the overview page.
 
    $url = $_SERVER['REQUEST_URI'];
 
    // This is an ajax request to render the overview page showing the three buttons
    if ($request_wrapper->has('page') && $request_wrapper->retrieve('page', $refinery->kindlyTo()->string()) == 'overview') {
        // Note: The ID of the replace signal is sent explicitly as GET parameter. This is a proof of concept
        // and may be subject to change, as the framework could send such parameters implicitly.
        $signalId = $request_wrapper->retrieve('replaceSignal', $refinery->kindlyTo()->string());
        $replaceSignal = new ReplaceContentSignal($signalId);
        $button1 = $factory->button()->standard('Go to page 1', '#')
            ->withOnClick($replaceSignal->withAsyncRenderUrl($url . '&page=1&replaceSignal=' . $signalId));
        $button2 = $factory->button()->standard('Go to page 2', '#')
            ->withOnClick($replaceSignal->withAsyncRenderUrl($url . '&page=2&replaceSignal=' . $signalId));
        $button3 = $factory->button()->standard('Go to page 3', '#')
            ->withOnClick($replaceSignal->withAsyncRenderUrl($url . '&page=3&replaceSignal=' . $signalId));
        $list = $factory->listing()->unordered([$button1, $button2, $button3]);
        echo $renderer->renderAsync($list);
        exit();
    }
 
    // This is an ajax request to render a page
    if ($request_wrapper->has('page')) {
        $page = $request_wrapper->retrieve('page', $refinery->kindlyTo()->int());
        $signalId = $request_wrapper->retrieve('replaceSignal', $refinery->kindlyTo()->string());
        $replaceSignal = new ReplaceContentSignal($signalId);
        $button = $factory->button()->standard('Back to Overview', '#')
            ->withOnClick($replaceSignal->withAsyncRenderUrl($url . '&page=overview&replaceSignal=' . $signalId));
        $intro = $factory->legacy("<p>You are viewing page $page</p>");
        echo $renderer->renderAsync([$intro, $button]);
        exit();
    }
 
    // This is the "normal" request to render the popover. Any content of the popover is rendered async.
    $popover = $factory->popover()->standard($factory->legacy(''))->withTitle('Pages');
    $asyncUrl = $url . '&page=overview&replaceSignal=' . $popover->getReplaceContentSignal()->getId();
    $popover = $popover->withAsyncContentUrl($asyncUrl);
    $button = $factory->button()->standard('Show Popover', '#')
        ->withOnClick($popover->getShowSignal());
    return $renderer->render([$popover, $button]);
}
 

Example 5: Show popover with vertical scrollbars

<?php
 
declare(strict_types=1);
 
namespace ILIAS\UI\examples\Popover\Standard;
 
function show_popover_with_vertical_scrollbars()
{
    global $DIC;
    $factory = $DIC->ui()->factory();
    $renderer = $DIC->ui()->renderer();
 
    // Note: A list should be rendered with the listing popover, e.g. $factory->popover()->listing()
    // However, at the moment there is no component present representing such list items, so this example
    // also uses a standard popover.
 
    $series = [
        'Breaking Bad',
        'Big Bang Theory',
        'Dexter',
        'Better Call Saul',
        'Narcos',
        'Ray Donovan',
        'Simpsons',
        'South Park',
        'Fargo',
        'Bloodline',
        'The Walking Dead',
        'New Girl',
        'Sons of Anarchy',
        'How I Met Your Mother',
    ];
    $list = $renderer->render($factory->listing()->unordered($series));
    // Note: The Popover does not restrict the height. It is the responsibility of the content component
    // to define the max height and to display vertical scrollbars, if necessary.
    // At the moment, the renderer of a component is not aware of the context it is rendering the component,
    // e.g. inside a Popover.
    // The inline code below simulates this behaviour. Here we want to reduce the
    // height of the list to 200px and display vertical scrollbars, if needed.
    $content = "<div style='max-height: 200px; overflow-y: auto; padding-right: 10px;'>{$list}</div>";
 
    $popover = $factory->popover()->standard($factory->legacy($content))->withTitle('Series');
    $button = $factory->button()->standard('Show me some Series', '#')
        ->withOnClick($popover->getShowSignal());
 
    return $renderer->render([$popover, $button]);
}
 

Relations

Parents
  1. UIComponent
  2. Popover