From 45980f3fdcb7200a6a5a1abc1d59c5e23085e559 Mon Sep 17 00:00:00 2001 From: Thomas Famula Date: Tue, 18 Jun 2019 15:42:54 +0200 Subject: [PATCH] Template for withonUpdate in Forms --- .../Init/classes/class.ilInitialisation.php | 1 + .../Component/Input/Container/Form/Form.php | 12 ++++- .../Input/Container/Form/Factory.php | 9 +++- .../Component/Input/Container/Form/Form.php | 40 ++++++++++++++- .../Input/Container/Form/Renderer.php | 23 +++++++-- .../Input/Container/Form/Standard.php | 5 +- .../Component/Input/Field/Renderer.php | 51 ++++++++++++------- .../templates/default/Input/tpl.standard.html | 2 +- src/UI/templates/js/Input/Container/form.js | 29 +++++++++++ 9 files changed, 145 insertions(+), 27 deletions(-) create mode 100644 src/UI/templates/js/Input/Container/form.js diff --git a/Services/Init/classes/class.ilInitialisation.php b/Services/Init/classes/class.ilInitialisation.php index 55f0bd2c7736..14a21e0d9473 100644 --- a/Services/Init/classes/class.ilInitialisation.php +++ b/Services/Init/classes/class.ilInitialisation.php @@ -1605,6 +1605,7 @@ public static function initUIFramework(\ILIAS\DI\Container $c) { }; $c["ui.factory.input.container.form"] = function($c) { return new ILIAS\UI\Implementation\Component\Input\Container\Form\Factory( + $c["ui.signal_generator"], $c["ui.factory.input.field"] ); }; diff --git a/src/UI/Component/Input/Container/Form/Form.php b/src/UI/Component/Input/Container/Form/Form.php index 9ef8160e042c..03d0011ae174 100644 --- a/src/UI/Component/Input/Container/Form/Form.php +++ b/src/UI/Component/Input/Container/Form/Form.php @@ -7,12 +7,15 @@ use ILIAS\UI\Component\Component; use ILIAS\Refinery\Transformation; +use ILIAS\UI\Component\JavaScriptBindable; +use ILIAS\UI\Component\Signal; +use ILIAS\UI\Component\Triggerable; use Psr\Http\Message\ServerRequestInterface; /** * This describes commonalities between all forms. */ -interface Form extends Component { +interface Form extends Component, JavaScriptBindable, Triggerable { /** * Get the inputs contained in the form. @@ -53,4 +56,11 @@ public function getData(); * TODO: there should be a further method to attach the different submit buttons */ + /** + * Get the signal to update this form + * + * @return Signal + */ + public function getUpdateSignal(); + } diff --git a/src/UI/Implementation/Component/Input/Container/Form/Factory.php b/src/UI/Implementation/Component/Input/Container/Form/Factory.php index d0964895071d..5ab626431847 100644 --- a/src/UI/Implementation/Component/Input/Container/Form/Factory.php +++ b/src/UI/Implementation/Component/Input/Container/Form/Factory.php @@ -6,16 +6,23 @@ use ILIAS\UI\Component\Input\Container\Form as F; use ILIAS\UI\Implementation\Component\Input; +use ILIAS\UI\Implementation\Component\SignalGeneratorInterface; class Factory implements F\Factory { + /** + * @var SignalGeneratorInterface + */ + protected $signal_generator; /** * @var Input\Field\Factory */ protected $field_factory; public function __construct( + SignalGeneratorInterface $signal_generator, Input\Field\Factory $field_factory ) { + $this->signal_generator = $signal_generator; $this->field_factory = $field_factory; } @@ -23,6 +30,6 @@ public function __construct( * @inheritdoc */ public function standard($post_url, array $inputs) { - return new Standard($this->field_factory, $post_url, $inputs); + return new Standard($this->signal_generator, $this->field_factory, $post_url, $inputs); } } diff --git a/src/UI/Implementation/Component/Input/Container/Form/Form.php b/src/UI/Implementation/Component/Input/Container/Form/Form.php index c55c1f312bb2..b52c281d4857 100644 --- a/src/UI/Implementation/Component/Input/Container/Form/Form.php +++ b/src/UI/Implementation/Component/Input/Container/Form/Form.php @@ -13,6 +13,9 @@ use ILIAS\Data; use ILIAS\Refinery; +use ILIAS\UI\Implementation\Component\JavaScriptBindable; +use ILIAS\UI\Implementation\Component\Signal; +use ILIAS\UI\Implementation\Component\SignalGeneratorInterface; use Psr\Http\Message\ServerRequestInterface; /** @@ -21,6 +24,7 @@ abstract class Form implements C\Input\Container\Form\Form, CI\Input\NameSource { use ComponentHelper; + use JavaScriptBindable; /** * @var C\Input\Field\Group */ @@ -35,12 +39,21 @@ abstract class Form implements C\Input\Container\Form\Form, CI\Input\NameSource * @var int */ private $count = 0; + /** + * @var SignalGeneratorInterface + */ + protected $signal_generator; + + /** + * @var Signal + */ + protected $update_signal; /** * @param array $inputs */ - public function __construct(Input\Field\Factory $field_factory, array $inputs) { + public function __construct(SignalGeneratorInterface $signal_generator, Input\Field\Factory $field_factory, array $inputs) { $classes = [CI\Input\Field\Input::class]; $this->checkArgListElements("input", $inputs, $classes); // TODO: this is a dependency and should be treated as such. `use` statements can be removed then. @@ -50,6 +63,8 @@ public function __construct(Input\Field\Factory $field_factory, array $inputs) { "" )->withNameFrom($this); $this->transformation = null; + $this->signal_generator = $signal_generator; + $this->initSignals(); } @@ -143,4 +158,27 @@ public function getNewName() { return $name; } + + /** + * @inheritdoc + */ + public function getUpdateSignal() { + return $this->update_signal; + } + + /** + * @inheritdoc + */ + public function withResetSignals() { + $clone = clone $this; + $clone->initSignals(); + return $clone; + } + + /** + * Set the update signal for this input + */ + protected function initSignals() { + $this->update_signal = $this->signal_generator->create(); + } } diff --git a/src/UI/Implementation/Component/Input/Container/Form/Renderer.php b/src/UI/Implementation/Component/Input/Container/Form/Renderer.php index 3a524ca30167..669087930308 100644 --- a/src/UI/Implementation/Component/Input/Container/Form/Renderer.php +++ b/src/UI/Implementation/Component/Input/Container/Form/Renderer.php @@ -5,6 +5,7 @@ namespace ILIAS\UI\Implementation\Component\Input\Container\Form; use ILIAS\UI\Implementation\Render\AbstractComponentRenderer; +use ILIAS\UI\Component\Input\Container\Form; use ILIAS\UI\Renderer as RendererInterface; use ILIAS\UI\Component; @@ -16,7 +17,7 @@ class Renderer extends AbstractComponentRenderer { public function render(Component\Component $component, RendererInterface $default_renderer) { $this->checkComponent($component); - if ($component instanceof Component\Input\Container\Form\Standard) { + if ($component instanceof Form\Standard) { return $this->renderStandard($component, $default_renderer); } @@ -24,9 +25,13 @@ public function render(Component\Component $component, RendererInterface $defaul } - protected function renderStandard(Component\Input\Container\Form\Standard $component, RendererInterface $default_renderer) { + protected function renderStandard(Form\Standard $component, RendererInterface $default_renderer) { $tpl = $this->getTemplate("tpl.standard.html", true, true); + $component = $this->registerSignals($component); + $id = $this->bindJavaScript($component); + $tpl->setVariable('ID_FORM', $id); + if($component->getPostURL()!= ""){ $tpl->setCurrentBlock("action"); $tpl->setVariable("URL", $component->getPostURL()); @@ -42,12 +47,24 @@ protected function renderStandard(Component\Input\Container\Form\Standard $compo $tpl->setVariable("BUTTONS_TOP", $default_renderer->render($submit_button)); $tpl->setVariable("BUTTONS_BOTTOM", $default_renderer->render($submit_button)); - $tpl->setVariable("INPUTS", $default_renderer->render($component->getInputGroup())); + $input_group = $component->getInputGroup(); + $input_group = $input_group->withOnUpdate($component->getUpdateSignal()); + $tpl->setVariable("INPUTS", $default_renderer->render($input_group)); return $tpl->get(); } + protected function registerSignals(Form\Form $form) { + $update = $form->getUpdateSignal(); + return $form->withAdditionalOnLoadCode(function($id) use ($update) { + $code = + "$(document).on('{$update}', function(event, signalData) { il.UI.form.onInputUpdate(event, signalData, '{$id}'); return false; });"; + return $code; + }); + } + + /** * @inheritdoc */ diff --git a/src/UI/Implementation/Component/Input/Container/Form/Standard.php b/src/UI/Implementation/Component/Input/Container/Form/Standard.php index 341824601f97..1d11f7bdac2f 100644 --- a/src/UI/Implementation/Component/Input/Container/Form/Standard.php +++ b/src/UI/Implementation/Component/Input/Container/Form/Standard.php @@ -6,6 +6,7 @@ use ILIAS\UI\Component as C; use ILIAS\UI\Implementation\Component\Input; +use ILIAS\UI\Implementation\Component\SignalGeneratorInterface; /** * This implements a standard form. @@ -18,8 +19,8 @@ class Standard extends Form implements C\Input\Container\Form\Standard { protected $post_url; - public function __construct(Input\Field\Factory $input_factory, $post_url, array $inputs) { - parent::__construct($input_factory, $inputs); + public function __construct(SignalGeneratorInterface $signal_generator, Input\Field\Factory $input_factory, $post_url, array $inputs) { + parent::__construct($signal_generator, $input_factory, $inputs); $this->checkStringArg("post_url", $post_url); $this->post_url = $post_url; } diff --git a/src/UI/Implementation/Component/Input/Field/Renderer.php b/src/UI/Implementation/Component/Input/Field/Renderer.php index e39b0e6d97f0..cd970cb223b8 100644 --- a/src/UI/Implementation/Component/Input/Field/Renderer.php +++ b/src/UI/Implementation/Component/Input/Field/Renderer.php @@ -53,6 +53,32 @@ public function registerResources(ResourceRegistry $registry) { $registry->register('./src/UI/templates/js/Input/Field/textarea.js'); $registry->register('./src/UI/templates/js/Input/Field/radioInput.js'); $registry->register('./src/UI/templates/js/Input/Field/input.js'); + $registry->register('./src/UI/templates/js/Input/Container/form.js'); + } + + + /** + * @param Input $input + * @return Input|\ILIAS\UI\Implementation\Component\JavaScriptBindable + */ + protected function setSignals(Input $input) { + foreach ($input->getTriggeredSignals() as $s) + { + $signals[] = [ + "signal_id" => $s->getSignal()->getId(), + "event" => $s->getEvent(), + "options" => $s->getSignal()->getOptions() + ]; + } + $signals = json_encode($signals); + + $input = $input->withAdditionalOnLoadCode(function ($id) use ($signals) { + $code = "il.UI.input.setSignalsForId('$id', $signals);"; + return $code; + }); + $input = $input->withAdditionalOnLoadCode($input->getUpdateOnLoadCode()); + + return $input; } @@ -129,19 +155,6 @@ protected function renderFieldGroups(Group $group, RendererInterface $default_re return $inputs; } - /** - * @param Component\JavascriptBindable $component - * @param $tpl - */ - protected function maybeRenderId(Component\JavascriptBindable $component, Template $tpl) { - $id = $this->bindJavaScript($component); - if ($id !== null) { - $tpl->setCurrentBlock("with_id"); - $tpl->setVariable("ID", $id); - $tpl->parseCurrentBlock(); - } - } - /** * @param Section $section @@ -302,11 +315,6 @@ protected function renderInputField(Template $tpl, Input $input, $id) { $tpl->setVariable("DISABLED", 'disabled="disabled"'); $tpl->parseCurrentBlock(); } - if ($id) { - $tpl->setCurrentBlock("id"); - $tpl->setVariable("ID", $id); - $tpl->parseCurrentBlock(); - } break; case ($input instanceof Select): $tpl = $this->renderSelectInput($tpl, $input); @@ -349,6 +357,12 @@ function ($id) use ($configuration) { break; } + $input = $this->setSignals($input); + $id = $this->bindJavaScript($input); + if ($id !== null) { + $tpl->setVariable("ID", $id); + } + return $tpl->get(); } @@ -492,6 +506,7 @@ protected function renderRadioField(Component\Input\Field\Radio $input, Renderer $input = $input->withAdditionalOnLoadCode(function ($id) { return "il.UI.Input.radio.init('$id');"; }); + $input = $this->setSignals($input); $id = $this->bindJavaScript($input); $input_tpl->setVariable("ID", $id); diff --git a/src/UI/templates/default/Input/tpl.standard.html b/src/UI/templates/default/Input/tpl.standard.html index 73000bfbbb67..1479f5dc0d5c 100644 --- a/src/UI/templates/default/Input/tpl.standard.html +++ b/src/UI/templates/default/Input/tpl.standard.html @@ -1,4 +1,4 @@ -
action="{URL}" method="post" novalidate="novalidate"> + action="{URL}" method="post" novalidate="novalidate">
{BUTTONS_TOP}
diff --git a/src/UI/templates/js/Input/Container/form.js b/src/UI/templates/js/Input/Container/form.js new file mode 100644 index 000000000000..6babfe8f39c8 --- /dev/null +++ b/src/UI/templates/js/Input/Container/form.js @@ -0,0 +1,29 @@ +/** + * Form + * + * @author + */ + +var il = il || {}; +il.UI = il.UI || {}; + +il.UI.form = (function ($) { + + /** + * + * @param event + * @param signalData + */ + var onInputUpdate = function (event, signalData) { + console.log(signalData.options.string_value); + }; + + + /** + * Public interface + */ + return { + onInputUpdate: onInputUpdate + }; + +})($); \ No newline at end of file