Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions components/ILIAS/UI/src/Component/Input/ViewControl/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@

namespace ILIAS\UI\Component\Input\ViewControl;

use ILIAS\UI\Component\Button\Button;
use ILIAS\UI\Component\Button\Month;
use ILIAS\UI\Component\Dropdown\Standard as StandardDropdown;

/**
* This describes the factory for (view-)controls.
*/
Expand Down Expand Up @@ -165,4 +169,35 @@ public function nullControl(): NullControl;
*/
public function mode(array $options): Mode;

/**
* ---
* description:
* purpose: >
* Section View Controls enable the switching between different sections of some data.
* Examples are subsequent days/weeks/months in a calendar or entries in a blog.
* composition: >
* Section View Controls are composed of three Buttons. The Button on the left carries
* a Back Glyph, the Button in the middle is either a Default-, Month Button or a
* Dropdown labeling the data displayed below, and the Button on the right carries a
* Next Glyph.
* effect: >
* Clicking on the Buttons left or right changes the selection of the displayed data by
* a fixed interval. Clicking the Button in the middle opens the sections hinted by the
* label of the button.
* rules:
* usage:
* 1: Dropdowns MUST NOT be used for any other purpose than skipping a section of the
* navigation (e.g. jumping from Chapter 1 to Chapter 5).
* ---
* @param Button $previous_action Button to be placed on the left.
* @param Button|Month|StandardDropdown $button Button to be placed in the middle.
* @param Button $next_action Button to be placed on the right.
* @return \ILIAS\UI\Component\Input\ViewControl\Section
*/
public function section(
Button $previous_action,
Button|Month|StandardDropdown $button,
Button $next_action
): Section;

}
38 changes: 38 additions & 0 deletions components/ILIAS/UI/src/Component/Input/ViewControl/Section.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\UI\Component\Input\ViewControl;

use ILIAS\UI\Component\Button\Button;
use ILIAS\UI\Component\Button\Month;
use ILIAS\UI\Component\Dropdown\Standard as StandardDropdown;
use ILIAS\UI\Component\Input\Container\ViewControl\ViewControlInput;

/**
* This describes a Section View Control.
*/
interface Section extends ViewControlInput
{
public function getPreviousActions(): Button;

public function getNextActions(): Button;

public function getSelectorButton(): Button|Month|StandardDropdown;
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
namespace ILIAS\UI\Implementation\Component\Input\ViewControl;

use ILIAS\UI\Component\Input\ViewControl as VCInterface;
use ILIAS\UI\Component\Button\Button;
use ILIAS\UI\Component\Button\Month;
use ILIAS\UI\Component\Dropdown\Standard as StandardDropdown;
use ILIAS\UI\Implementation\Component\SignalGeneratorInterface;
use ILIAS\Data\Factory as DataFactory;
use ILIAS\Refinery\Factory as Refinery;
Expand Down Expand Up @@ -96,4 +99,18 @@ public function mode(array $options): VCInterface\Mode
$options
);
}

public function section(
Button $previous_action,
Button|Month|StandardDropdown $button,
Button $next_action
): Section {
return new Section(
$this->data_factory,
$this->refinery,
$previous_action,
$button,
$next_action
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use ILIAS\UI\Implementation\Render\ResourceRegistry;
use ILIAS\UI\Renderer as RendererInterface;
use ILIAS\UI\Component;
use ILIAS\UI\Component\Button\Button;
use ILIAS\UI\Implementation\Render\Template;
use LogicException;

class Renderer extends AbstractComponentRenderer
Expand Down Expand Up @@ -54,6 +56,8 @@ public function render(Component\Component $component, RendererInterface $defaul
return '';
case ($component instanceof Component\Input\ViewControl\Mode):
return $this->renderMode($component, $default_renderer);
case ($component instanceof Component\Input\ViewControl\Section):
return $this->renderSection($component, $default_renderer);

default:
$this->cannotHandleComponent($component);
Expand Down Expand Up @@ -121,6 +125,44 @@ protected function renderFieldSelection(FieldSelection $component, RendererInter
return $tpl->get();
}

protected function renderSection(Section $component, RendererInterface $default_renderer): string
{
$tpl = $this->getTemplate("tpl.section.html", true, true);

$tpl->setVariable("BUTTON", $default_renderer->render($component->getSelectorButton()));
$this->renderSectionButton($component->getPreviousActions(), $tpl, "prev");
$this->renderSectionButton($component->getNextActions(), $tpl, "next");

return $tpl->get();
}

protected function renderSectionButton(Button $component, Template $tpl, string $type): void
{
$upper_type = strtoupper($type);
$action = $component->getAction();
$tpl->setVariable($upper_type . "_ACTION", $action);
$tpl->setVariable(
$upper_type . "_LABEL",
$this->txt($type === "next" ? "next" : "previous")
);

if ($component->isActive()) {
$tpl->setCurrentBlock($type . "_with_href");
$tpl->setVariable($upper_type . "_HREF", $action);
$tpl->parseCurrentBlock();
} else {
$tpl->touchBlock($type . "_disabled");
}

$id = $this->bindJavaScript($component);
if (!$id) {
$id = $this->createId();
}
$tpl->setCurrentBlock($type . "_with_id");
$tpl->setVariable($upper_type . "_ID", $id);
$tpl->parseCurrentBlock();
}

protected function renderSortation(Sortation $component, RendererInterface $default_renderer): string
{
$tpl = $this->getTemplate("tpl.viewcontrol_sortation.html", true, true);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\UI\Implementation\Component\Input\ViewControl;

use ILIAS\Data\Factory as DataFactory;
use ILIAS\Refinery\Factory as Refinery;
use ILIAS\UI\Component\Button\Button;
use ILIAS\UI\Component\Button\Month;
use ILIAS\UI\Component\Dropdown\Standard as StandardDropdown;
use ILIAS\UI\Component\Input\ViewControl as ViewControlInterface;

class Section extends ViewControlInput implements ViewControlInterface\Section
{
protected Button $previous_action;
protected Button|Month|StandardDropdown $button;
protected Button $next_action;

public function __construct(
DataFactory $data_factory,
Refinery $refinery,
Button $previous_action,
Button|Month|StandardDropdown $button,
Button $next_action
) {
parent::__construct($data_factory, $refinery);
$this->previous_action = $previous_action;
$this->button = $button;
$this->next_action = $next_action;
}

protected function isClientSideValueOk($value): bool
{
return $value === null;
}

public function getPreviousActions(): Button
{
return $this->previous_action;
}

public function getNextActions(): Button
{
return $this->next_action;
}

public function getSelectorButton(): Button|Month|StandardDropdown
{
return $this->button;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\UI\examples\Input\ViewControl\Section;

/**
* ---
* description: >
* Example of a Section View Control using a Dropdown to navigate between non-adjacent sections.
*
* expected output: >
* ILIAS shows three controls next to each other: a "Back" glyph, a dropdown "Second Section" and a "Next" glyph.
* The current section is shown below the controls. Clicking "Back" or "Next" reloads the page with the current
* section changed. Selecting an entry in the dropdown reloads the page with the selected section.
* ---
*/
function dropdown(): string
{
global $DIC;
$f = $DIC->ui()->factory();
$r = $DIC->ui()->renderer();
$request = $DIC->http()->request();

$sections = ["First Section", "Second Section", "Third Section"];
$parameter = "Section";
$current_section = 1;
$query_params = $request->getQueryParams();
if (isset($query_params[$parameter])
&& (is_int($query_params[$parameter])
|| (is_string($query_params[$parameter]) && ctype_digit($query_params[$parameter])))
&& array_key_exists((int) $query_params[$parameter], $sections)
) {
$current_section = (int) $query_params[$parameter];
}

$target = $request->getRequestTarget();
$separator = str_contains($target, "?") ? "&" : "?";
$action = static fn(int $section): string => $target . $separator . $parameter . "=" . $section;

$back = $f->button()->standard("Back", $action(($current_section - 1 + count($sections)) % count($sections)));
$next = $f->button()->standard("Next", $action(($current_section + 1) % count($sections)));
$section_links = [];
foreach ($sections as $index => $label) {
$section_links[] = $f->link()->standard($label, $action($index));
}
$middle = $f->dropdown()->standard($section_links)->withLabel($sections[$current_section]);
$section = $f->input()->viewControl()->section($back, $middle, $next);

$container = $f->input()->container()->viewControl()->standard([$section])
->withRequest($request);

return $r->render([
$f->legacy()->content('<p role="status">Current section: ' . $sections[$current_section] . '</p>'),
$container
]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

/**
* This file is part of ILIAS, a powerful learning management system
* published by ILIAS open source e-Learning e.V.
*
* ILIAS is licensed with the GPL-3.0,
* see https://www.gnu.org/licenses/gpl-3.0.en.html
* You should have received a copy of said license along with the
* source code, too.
*
* If this is not the case or you just want to try ILIAS, you'll find
* us at:
* https://www.ilias.de
* https://github.com/ILIAS-eLearning
*
*********************************************************************/

declare(strict_types=1);

namespace ILIAS\UI\examples\Input\ViewControl\Section;

/**
* ---
* description: >
* Example of a Section View Control using a Dropdown with a long label to demonstrate responsive behavior.
*
* expected output: >
* ILIAS shows three controls next to each other: a "Back" glyph, a dropdown with a long label and a "Next" glyph.
* The current section is shown below the controls. Clicking "Back" or "Next" reloads the page with the current
* section changed. Selecting an entry in the dropdown reloads the page with the selected section.
* ---
*/
function dropdown_with_long_title(): string
{
global $DIC;
$f = $DIC->ui()->factory();
$r = $DIC->ui()->renderer();
$request = $DIC->http()->request();

$long_title = "Second section with a very long title to check the responsive behaviour";
$sections = ["First Section", $long_title, "Third Section"];
$parameter = "Section";
$current_section = 1;
$query_params = $request->getQueryParams();
if (isset($query_params[$parameter])
&& (is_int($query_params[$parameter])
|| (is_string($query_params[$parameter]) && ctype_digit($query_params[$parameter])))
&& array_key_exists((int) $query_params[$parameter], $sections)
) {
$current_section = (int) $query_params[$parameter];
}

$target = $request->getRequestTarget();
$separator = str_contains($target, "?") ? "&" : "?";
$action = static fn(int $section): string => $target . $separator . $parameter . "=" . $section;

$back = $f->button()->standard("Back", $action(($current_section - 1 + count($sections)) % count($sections)));
$next = $f->button()->standard("Next", $action(($current_section + 1) % count($sections)));
$section_links = [];
foreach ($sections as $index => $label) {
$section_links[] = $f->link()->standard($label, $action($index));
}
$middle = $f->dropdown()->standard($section_links)->withLabel($sections[$current_section]);
$section = $f->input()->viewControl()->section($back, $middle, $next);

$container = $f->input()->container()->viewControl()->standard([$section])
->withRequest($request);

return $r->render([
$f->legacy()->content('<p role="status">Current section: ' . $sections[$current_section] . '</p>'),
$container
]);
}
Loading
Loading