From 3dab4e4841c4009372674ab999b3534122beb1e0 Mon Sep 17 00:00:00 2001 From: Thibeau Fuhrer Date: Fri, 15 Nov 2024 15:20:44 +0100 Subject: [PATCH] [FIX] UI: align Container\Form context renderers. --- .../Component/Input/Container/Form/Form.php | 16 ------ .../Container/Form/FormRendererFactory.php | 6 +-- ...rmWithoutSubmitButtonsContextRenderer.php} | 53 ++++--------------- .../Input/Container/Form/Renderer.php | 44 ++------------- .../Input/Container/Form/Standard.php | 17 ++++-- ...t.html => tpl.without_submit_buttons.html} | 4 +- ...t.php => FormWithoutSubmitButtonsTest.php} | 16 +++--- 7 files changed, 41 insertions(+), 115 deletions(-) rename components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/{NoButtonsContextRenderer.php => FormWithoutSubmitButtonsContextRenderer.php} (61%) rename components/ILIAS/UI/src/templates/default/Input/{tpl.no_submit.html => tpl.without_submit_buttons.html} (81%) rename components/ILIAS/UI/tests/Component/Input/Container/Form/{NoSubmitFormTest.php => FormWithoutSubmitButtonsTest.php} (92%) diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Form.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Form.php index 2a8a684785d6..196f8998842e 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Form.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Form.php @@ -61,20 +61,4 @@ protected function extractRequestData(ServerRequestInterface $request): InputDat { return new PostDataFromServerRequest($request); } - - /** - * @inheritdoc - */ - public function getPromptButtons(): array - { - return []; - } - - /** - * @inheritdoc - */ - public function getPromptTitle(): string - { - return ''; - } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormRendererFactory.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormRendererFactory.php index 204d6fce8a34..28a0ca681817 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormRendererFactory.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormRendererFactory.php @@ -25,17 +25,17 @@ class FormRendererFactory extends Render\DefaultRendererFactory { - public const NO_BUTTONS_FORM = [ + public const FORM_CONTEXTS_WITHOUT_BUTTONS = [ 'StateStatePrompt', 'RoundTripModal', ]; public function getRendererInContext(Component\Component $component, array $contexts): Render\AbstractComponentRenderer { - $has_context_without_buttons = array_intersect(self::NO_BUTTONS_FORM, $contexts); + $has_context_without_buttons = array_intersect(self::FORM_CONTEXTS_WITHOUT_BUTTONS, $contexts); if (! empty($has_context_without_buttons)) { - return new NoButtonsContextRenderer( + return new FormWithoutSubmitButtonsContextRenderer( $this->ui_factory, $this->tpl_factory, $this->lng, diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/NoButtonsContextRenderer.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormWithoutSubmitButtonsContextRenderer.php similarity index 61% rename from components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/NoButtonsContextRenderer.php rename to components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormWithoutSubmitButtonsContextRenderer.php index 3f824cb58ad8..1696a672c11f 100644 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/NoButtonsContextRenderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/FormWithoutSubmitButtonsContextRenderer.php @@ -27,25 +27,27 @@ use ILIAS\UI\Component; use LogicException; -class NoButtonsContextRenderer extends AbstractComponentRenderer +class FormWithoutSubmitButtonsContextRenderer extends Renderer { /** * @inheritdoc */ public function render(Component\Component $component, RendererInterface $default_renderer): string { - if (!$component instanceof Form\Form) { - $this->cannotHandleComponent($component); + if ($component instanceof Form\Standard) { + return $this->renderFormWithoutSubmitButtons($component, $default_renderer); } - return $this->renderNoSubmit($component, $default_renderer); + + $this->cannotHandleComponent($component); } - protected function renderNoSubmit( - Form\Form $component, + protected function renderFormWithoutSubmitButtons( + Form\Standard $component, RendererInterface $default_renderer ): string { - $tpl = $this->getTemplate("tpl.no_submit.html", true, true); + $tpl = $this->getTemplate("tpl.without_submit_buttons.html", true, true); + $this->maybeAddDedicatedName($component, $tpl); $this->maybeAddRequired($component, $tpl); $this->addPostURL($component, $tpl); $this->maybeAddError($component, $tpl); @@ -75,41 +77,4 @@ static function (string $id) use ($component): string { return $tpl->get(); } - - protected function addPostURL(Component\Input\Container\Form\FormWithPostURL $component, Template $tpl): void - { - if ('' !== ($url = $component->getPostURL())) { - $tpl->setCurrentBlock("action"); - $tpl->setVariable("URL", $url); - $tpl->parseCurrentBlock(); - } - } - - protected function maybeAddError(Form\Form $component, Template $tpl): void - { - if (null !== ($error = $component->getError())) { - $tpl->setCurrentBlock("error"); - $tpl->setVariable("ERROR", $error); - $tpl->parseCurrentBlock(); - } - } - - protected function maybeAddRequired(Form\Form $component, Template $tpl): void - { - if ($component->hasRequiredInputs()) { - $tpl->setVariable("TXT_REQUIRED_TOP", $this->txt("required_field")); - $tpl->setVariable("TXT_REQUIRED", $this->txt("required_field")); - } - } - - /** - * @inheritdoc - */ - protected function getComponentInterfaceName(): array - { - return [ - Component\Input\Container\Form\Standard::class, - FormWithoutSubmitButton::class, - ]; - } } diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Renderer.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Renderer.php index db1fdada1866..1bbc5507ddb6 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Renderer.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Renderer.php @@ -38,20 +38,14 @@ public function render(Component\Component $component, RendererInterface $defaul return $this->renderStandard($component, $default_renderer); } - if ($component instanceof Form\FormWithoutSubmitButton) { - return $this->renderNoSubmit($component, $default_renderer); - } - $this->cannotHandleComponent($component); } protected function renderStandard(Form\Standard $component, RendererInterface $default_renderer): string { $tpl = $this->getTemplate("tpl.standard.html", true, true); - if ($component->getDedicatedName() !== null) { - $tpl->setVariable("NAME", 'name="' . $component->getDedicatedName() . '"'); - } + $this->maybeAddDedicatedName($component, $tpl); $this->maybeAddRequired($component, $tpl); $this->addPostURL($component, $tpl); $this->maybeAddError($component, $tpl); @@ -68,39 +62,11 @@ protected function renderStandard(Form\Standard $component, RendererInterface $d return $tpl->get(); } - protected function renderNoSubmit(Form\FormWithoutSubmitButton $component, RendererInterface $default_renderer): string + protected function maybeAddDedicatedName(Form\Form $component, Template $tpl): void { - $tpl = $this->getTemplate("tpl.no_submit.html", true, true); - - $this->maybeAddRequired($component, $tpl); - $this->addPostURL($component, $tpl); - $this->maybeAddError($component, $tpl); - - $tpl->setVariable("INPUTS", $default_renderer->render($component->getInputGroup())); - - /** @var $component Form\FormWithoutSubmitButton */ - $enriched_component = $component->withAdditionalOnLoadCode( - static function (string $id) use ($component): string { - return " - // @TODO: we need to refactor the signal-management to prevent using jQuery here. - $(document).on('{$component->getSubmitSignal()}', function () { - let form = document.getElementById('$id'); - if (!form instanceof HTMLFormElement) { - throw new Error(`Element '$id' is not an instance of HTMLFormElement.`); - } - - // @TODO: we should use the triggering button as an emitter here. When doing - // so, please also change file.js processFormSubmissionHook(). - form.requestSubmit(); - }); - "; - } - ); - - $id = $this->bindJavaScript($enriched_component) ?? $this->createId(); - $tpl->setVariable("ID", $id); - - return $tpl->get(); + if ($component->getDedicatedName() !== null) { + $tpl->setVariable("NAME", 'name="' . $component->getDedicatedName() . '"'); + } } protected function addPostURL(Component\Input\Container\Form\FormWithPostURL $component, Template $tpl): void diff --git a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php index 79da96881912..890fc4c5f663 100755 --- a/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php +++ b/components/ILIAS/UI/src/Implementation/Component/Input/Container/Form/Standard.php @@ -25,6 +25,7 @@ use ILIAS\UI\Implementation\Component\Input; use ILIAS\UI\Implementation\Component\Input\NameSource; use ILIAS\UI\Implementation\Component\SignalGeneratorInterface; +use ILIAS\UI\Implementation\Component\Prompt\IsPromptContentInternal; use ILIAS\UI\Component\Signal; use ILIAS\UI\Implementation\Component\JavaScriptBindable as JavaScriptBindableTrait; use ILIAS\UI\Component\JavaScriptBindable; @@ -32,7 +33,7 @@ /** * This implements a standard form. */ -class Standard extends Form implements C\Input\Container\Form\Standard, JavaScriptBindable +class Standard extends Form implements C\Input\Container\Form\Standard, IsPromptContentInternal, JavaScriptBindable { use HasPostURL; use JavaScriptBindableTrait; @@ -55,10 +56,10 @@ public function __construct( /** * @inheritDoc */ - public function withSubmitLabel(string $caption): C\Input\Container\Form\Standard + public function withSubmitLabel(string $label): C\Input\Container\Form\Standard { $clone = clone $this; - $clone->submit_caption = $caption; + $clone->submit_caption = $label; return $clone; } @@ -70,6 +71,16 @@ public function getSubmitLabel(): ?string return $this->submit_caption; } + public function getPromptButtons(): array + { + return []; + } + + public function getPromptTitle(): string + { + return ''; + } + public function getSubmitSignal(): Signal { return $this->submit_signal; diff --git a/components/ILIAS/UI/src/templates/default/Input/tpl.no_submit.html b/components/ILIAS/UI/src/templates/default/Input/tpl.without_submit_buttons.html similarity index 81% rename from components/ILIAS/UI/src/templates/default/Input/tpl.no_submit.html rename to components/ILIAS/UI/src/templates/default/Input/tpl.without_submit_buttons.html index 3d65d5a7f8e3..a4f85fe66f40 100755 --- a/components/ILIAS/UI/src/templates/default/Input/tpl.no_submit.html +++ b/components/ILIAS/UI/src/templates/default/Input/tpl.without_submit_buttons.html @@ -1,8 +1,6 @@
describedby="{ERROR_ID}" {NAME} action="{URL}" method="post" novalidate="novalidate"> -
- {ERROR} -
+
{ERROR_LABEL}: {ERROR}
{INPUTS} diff --git a/components/ILIAS/UI/tests/Component/Input/Container/Form/NoSubmitFormTest.php b/components/ILIAS/UI/tests/Component/Input/Container/Form/FormWithoutSubmitButtonsTest.php similarity index 92% rename from components/ILIAS/UI/tests/Component/Input/Container/Form/NoSubmitFormTest.php rename to components/ILIAS/UI/tests/Component/Input/Container/Form/FormWithoutSubmitButtonsTest.php index cbf9293adbd6..10bc86fc7937 100755 --- a/components/ILIAS/UI/tests/Component/Input/Container/Form/NoSubmitFormTest.php +++ b/components/ILIAS/UI/tests/Component/Input/Container/Form/FormWithoutSubmitButtonsTest.php @@ -56,7 +56,7 @@ public function getNewDedicatedName(string $dedicated_name): string /** * @author Thibeau Fuhrer */ -class NoSubmitFormTest extends \ILIAS_UI_TestBase +class FormWithoutSubmitButtonsTest extends \ILIAS_UI_TestBase { protected SignalGenerator $signal_generator; protected NameSource $namesource; @@ -144,7 +144,8 @@ public function testRenderWithRequiredInputs(): void public function testRenderWithError(): void { $post_url = 'http://ilias.localhost/some_url?param1=foo¶m2=bar'; - $error_lang_var = 'ui_error_in_group'; + $error_lang_var = 'ui_error'; + $error_lang_var_in_group = 'ui_error_in_group'; $dummy_input = $this->buildInputFactory()->text('test_label')->withAdditionalTransformation( $this->refinery->custom()->constraint( @@ -171,11 +172,12 @@ static function ($value): bool { $form = $form->withRequest($request); $data = $form->getData(); - $expected_html = - "" . - "
$error_lang_var
" . - $dummy_input->getCanonicalName() . - ""; + $expected_html = << +
$error_lang_var:$error_lang_var_in_group +
{$dummy_input->getCanonicalName()} + +EOT; $context = $this->createMock(\ILIAS\UI\Component\Modal\RoundTrip::class); $context->method('getCanonicalName')->willReturn('RoundTripModal');