From 156692246d78857a66a5fd639a4cfa51996f6e55 Mon Sep 17 00:00:00 2001 From: Alexander Killing Date: Sun, 14 Oct 2018 17:25:34 +0200 Subject: [PATCH] cherry picked changes in toggle button pr up to 3ef17da1ce2354b0356b380310bf2dcec309d75e --- src/UI/Component/Button/Factory.php | 11 ++-- src/UI/Component/Button/Toggle.php | 27 +++++++-- .../Component/Button/Factory.php | 4 +- .../Component/Button/Renderer.php | 57 ++++++++---------- .../Component/Button/Toggle.php | 58 ++++++++++++++----- src/UI/Implementation/Component/Triggerer.php | 2 +- src/UI/examples/Button/Toggle/base.php | 30 ++-------- src/UI/templates/default/Button/toggle.less | 37 ++++++------ src/UI/templates/js/Button/button.js | 35 ++++++----- templates/default/less/variables.less | 25 ++++++++ 10 files changed, 167 insertions(+), 119 deletions(-) diff --git a/src/UI/Component/Button/Factory.php b/src/UI/Component/Button/Factory.php index 4caac49e8c2a..07e591cd03c6 100644 --- a/src/UI/Component/Button/Factory.php +++ b/src/UI/Component/Button/Factory.php @@ -303,12 +303,13 @@ public function bulky($icon_or_glyph, $label, $action); * The state of the Toggle Button MUST be indicated for screen readers * by using the aria-pressed attribute. * --- - * @param string $label - * @param string|Signal $action - * @param string|Signal $action_off - * @param bool $is_on + * @param string $label + * @param string|Signal $toggle_on_action action performed when button changes from off to on + * @param string|Signal $toggle_off_action action performed when button changes from on to off + * @param bool $is_on + * @param Signal $click_signal action performed when button is clicked * @return \ILIAS\UI\Component\Button\Toggle */ - public function toggle($label, $action, $action_off, $is_on = false); + public function toggle($label, $on_action, $off_action, $is_on = false, $click_signal = null); } diff --git a/src/UI/Component/Button/Toggle.php b/src/UI/Component/Button/Toggle.php index a62f7ed11871..2673110f7e8f 100644 --- a/src/UI/Component/Button/Toggle.php +++ b/src/UI/Component/Button/Toggle.php @@ -3,8 +3,8 @@ /* Copyright (c) 2018 Thomas Famula Extended GPL, see docs/LICENSE */ namespace ILIAS\UI\Component\Button; -//use ILIAS\UI\Component\Signal; -use ILIAS\UI\Implementation\Component\TriggeredSignal; +use ILIAS\UI\Component\Signal; +//use ILIAS\UI\Implementation\Component\TriggeredSignal; /** @@ -20,12 +20,29 @@ interface Toggle extends Button { public function isOn(); /** - * Get the action of the Toggle Button when it is off. + * Get the action of the Toggle Button when it is set from off to on. * - * @return string|TriggeredSignal + * @return string|Signal[] + */ + public function getActionOn(); + + /** + * Get the action of the Toggle Button when it is set from on to off. + * + * @return string|Signal[] */ public function getActionOff(); - //public function withOnClickOff(Signal $signal); + /** + * @param Signal $signal + * @return Toggle + */ + public function withAdditionalToggleOnSignal(Signal $signal); + + /** + * @param Signal $signal + * @return Toggle + */ + public function withAdditionalToggleOffSignal(Signal $signal); } \ No newline at end of file diff --git a/src/UI/Implementation/Component/Button/Factory.php b/src/UI/Implementation/Component/Button/Factory.php index 3a3f84d241af..32619c9021ab 100644 --- a/src/UI/Implementation/Component/Button/Factory.php +++ b/src/UI/Implementation/Component/Button/Factory.php @@ -59,7 +59,7 @@ public function bulky($icon_or_glyph, $label, $action) { /** * @inheritdoc */ - public function toggle($label, $action, $action_off, $is_on = false) { - return new Toggle($label, $action, $action_off, $is_on); + public function toggle($label, $on_action, $off_action, $is_on = false, $click_signal = null) { + return new Toggle($label, $on_action, $off_action, $is_on, $click_signal); } } diff --git a/src/UI/Implementation/Component/Button/Renderer.php b/src/UI/Implementation/Component/Button/Renderer.php index 080183309abf..7db532b637df 100644 --- a/src/UI/Implementation/Component/Button/Renderer.php +++ b/src/UI/Implementation/Component/Button/Renderer.php @@ -4,6 +4,7 @@ namespace ILIAS\UI\Implementation\Component\Button; +use ILIAS\UI\Implementation\Component\Signal; use ILIAS\UI\Implementation\Render\AbstractComponentRenderer; use ILIAS\UI\Renderer as RendererInterface; use ILIAS\UI\Component; @@ -127,52 +128,40 @@ protected function renderClose($component) { protected function renderToggle(Component\Button\Toggle $component) { $tpl = $this->getTemplate("tpl.toggle.html", true, true); - $on_action = $component->getAction(); + $on_action = $component->getActionOn(); $off_action = $component->getActionOff(); + $on_url = (is_string($on_action)) + ? $on_action + : ""; - if (is_string($on_action)) - { - $on_url = $on_action; - $on_options = "{}"; - } - else - { - $on_url = ""; - $on_signal = $on_action->getSignal(); - $on_event = $on_action->getEvent(); - $on_options = json_encode($on_signal->getOptions()); - } + $off_url = (is_string($off_action)) + ? $off_action + : ""; - if (is_string($off_action)) - { - $off_url = $off_action; - $off_options = "{}"; - } - else + $signals = []; + + foreach ($component->getTriggeredSignals() as $s) { - $off_url = ""; - $off_signal = $off_action->getSignal(); - $off_event = $off_action->getEvent(); - $off_options = json_encode($off_signal->getOptions()); + $signals[] = [ + "signal_id" => $s->getSignal()->getId(), + "event" => $s->getEvent(), + "options" => $s->getSignal()->getOptions() + ]; + } + $signals = json_encode($signals); if ($component->isActive()) { $component = $component->withAdditionalOnLoadCode(function ($id) - use ($on_url, $on_signal, $on_event, $on_options, - $off_url, $off_signal, $off_event, $off_options) { - return "$('#$id').on('click', function(event) { - il.UI.button.handleToggleClick(event, '$id', '$on_url', { - 'id' : '{$on_signal}', 'event' : '{$on_event}', - 'triggerer' : $('#{$id}'), - 'options' : JSON.parse('{$on_options}')}, '$off_url', { - 'id' : '{$off_signal}', 'event' : '{$off_event}', - 'triggerer' : $('#{$id}'), - 'options' : JSON.parse('{$off_options}') - }); + use ($on_url, $off_url, $signals) { + $code = "$('#$id').on('click', function(event) { + il.UI.button.handleToggleClick(event, '$id', '$on_url', '$off_url', $signals); return false; // stop event propagation });"; + //var_dump($code); exit; + return $code; }); } else { $tpl->touchBlock("disabled"); diff --git a/src/UI/Implementation/Component/Button/Toggle.php b/src/UI/Implementation/Component/Button/Toggle.php index 92c66ef23b31..bf22c6b09a4a 100644 --- a/src/UI/Implementation/Component/Button/Toggle.php +++ b/src/UI/Implementation/Component/Button/Toggle.php @@ -9,6 +9,7 @@ use ILIAS\UI\Implementation\Component\JavaScriptBindable; use ILIAS\UI\Implementation\Component\Triggerer; use ILIAS\UI\Implementation\Component\TriggeredSignal; +use ILIAS\UI\Component\Signal; class Toggle extends Button implements C\Button\Toggle { use ComponentHelper; @@ -28,34 +29,43 @@ class Toggle extends Button implements C\Button\Toggle { /** * @var string|null */ - protected $action_off; + protected $action_off = null; - protected $action_off_signal; - protected $action_on_signal; + /** + * @var string|null + */ + protected $action_on = null; - public function __construct($label, $action, $action_off, $is_on) + /** + * @inheritdoc + */ + public function __construct($label, $action_on, $action_off, $is_on, Signal $click = null) { $this->checkStringArg("label", $label); - $this->checkStringOrSignalArg("action", $action); + $this->checkStringOrSignalArg("action", $action_on); $this->checkStringOrSignalArg("action_off", $action_off); $this->checkBoolArg("is_on", $is_on); $this->label = $label; - if (is_string($action)) { - $this->action = $action; + $button_action = (is_null($click)) + ? "" // no way to resolve conflicting string actions + : $click; + + parent::__construct($label, $button_action); + + if (is_string($action_on)) { + $this->action_on = $action_on; } else { - $this->action = null; - $this->action_on_signal = new TriggeredSignal($action, "click"); + $this->setTriggeredSignal($action_on, "toggle_on"); } if (is_string($action_off)) { $this->action_off = $action_off; } else { - $this->action_off = null; - $this->action_off_signal = new TriggeredSignal($action_off, "click"); + $this->setTriggeredSignal($action_off, "toggle_off"); } $this->is_on = $is_on; @@ -82,18 +92,34 @@ public function getActionOff() if ($this->action_off !== null) { return $this->action_off; } - return $this->action_off_signal; + + return $this->getTriggeredSignalsFor("toggle_off"); } /** * @inheritdoc */ - public function getAction() + public function getActionOn() { - if ($this->action !== null) { - return $this->action; + if ($this->action_on !== null) { + return $this->action_on; } - return $this->action_on_signal; + + return $this->getTriggeredSignalsFor("toggle_on"); + } + + /** + * @inheritdoc + */ + public function withAdditionalToggleOnSignal(Signal $signal) { + return $this->appendTriggeredSignal($signal, "toggle_on"); + } + + /** + * @inheritdoc + */ + public function withAdditionalToggleOffSignal(Signal $signal) { + return $this->appendTriggeredSignal($signal, "toggle_off"); } } diff --git a/src/UI/Implementation/Component/Triggerer.php b/src/UI/Implementation/Component/Triggerer.php index 5dea1cfc2670..0970ed354ee4 100644 --- a/src/UI/Implementation/Component/Triggerer.php +++ b/src/UI/Implementation/Component/Triggerer.php @@ -75,7 +75,7 @@ public function getTriggeredSignals() { * Get signals that are triggered for a certain event. * * @param string - * @return \ILIAS\UI\Component\Signal + * @return \ILIAS\UI\Component\Signal[] */ public function getTriggeredSignalsFor($event) { if (!isset($this->triggered_signals[$event])) { diff --git a/src/UI/examples/Button/Toggle/base.php b/src/UI/examples/Button/Toggle/base.php index 907478cfe67e..ec2e696ed095 100644 --- a/src/UI/examples/Button/Toggle/base.php +++ b/src/UI/examples/Button/Toggle/base.php @@ -4,34 +4,14 @@ function base() { $factory = $DIC->ui()->factory(); $renderer = $DIC->ui()->renderer(); - $message = 'Are you sure you want to delete the following items?'; + $message1 = 'Toggle Button has been turned on'; + $message2 = 'Toggle Button has been turned off'; $form_action = $DIC->ctrl()->getFormActionByClass('ilsystemstyledocumentationgui'); - $icon = $factory->image()->standard('./templates/default/images/icon_crs.svg', ''); - $modal = $factory->modal()->interruptive('My Title', $message, $form_action) - ->withAffectedItems(array( - $factory->modal()->interruptiveItem(10, 'Course 1', $icon, 'Some description text'), - $factory->modal()->interruptiveItem(20, 'Course 2', $icon, 'Another description text'), - $factory->modal()->interruptiveItem(30, 'Course 3', $icon, 'Last but not least, a description'), - )); - $modal2 = $factory->modal()->interruptive('Your Title', $message, $form_action) - ->withAffectedItems(array( - $factory->modal()->interruptiveItem(40, 'Course 4', $icon, 'Some description text'), - $factory->modal()->interruptiveItem(50, 'Course 5', $icon, 'Another description text'), - $factory->modal()->interruptiveItem(60, 'Course 6', $icon, 'Last but not least, a description'), - )); + $modal = $factory->modal()->interruptive('ON', $message1, $form_action); + $modal2 = $factory->modal()->interruptive('OFF', $message2, $form_action); $button = $factory->button()->toggle("", $modal->getShowSignal(), $modal2->getShowSignal()); - // Display POST data of affected items in a panel - $panel = ''; - if (isset($_POST['interruptive_items'])) { - $panel = $factory->panel()->standard( - 'Affected Items', - $factory->legacy(print_r($_POST['interruptive_items'], true)) - ); - $panel = $renderer->render($panel); - } - - return $renderer->render([$button, $modal, $modal2]) . $panel; + return $renderer->render([$button, $modal, $modal2]); } \ No newline at end of file diff --git a/src/UI/templates/default/Button/toggle.less b/src/UI/templates/default/Button/toggle.less index bda2b9cda043..ded1b78c4e35 100644 --- a/src/UI/templates/default/Button/toggle.less +++ b/src/UI/templates/default/Button/toggle.less @@ -1,33 +1,34 @@ .il-toggle-button { position: relative; - //display: inline-block; - height: 19px; - padding: 0px 25px; - border: 1px solid rgba(0,0,0,0.1); - border-radius: 40px; - background: lightgrey; + display: inline-block; + height: @il-btn-toggle-height; + padding-left: @il-btn-toggle-padding; + padding-right: @il-btn-toggle-padding; + border: @il-btn-toggle-border @il-btn-toggle-border-color; + border-radius: @il-btn-toggle-border-radius; + background: @il-disabled-btn-toggle-bg; cursor: pointer; } .il-toggle-button .il-toggle-switch { position: absolute; - top: -4px; - left: -6%; - width: 25px; - height: 25px; - border: 1px solid rgba(0,0,0,0.2); - border-radius: 40px; - background: grey; + top: @il-btn-toggle-switch-position-top; + left: @il-disabled-btn-toggle-switch-position-left; + width: @il-btn-toggle-switch-size; + height: @il-btn-toggle-switch-size; + border: @il-btn-toggle-border @il-btn-toggle-switch-border-color; + border-radius: @il-btn-toggle-border-radius; + background: @il-disabled-btn-toggle-switch-color; - -webkit-transition: all 0.25s ease-in-out; /* Safari */ - transition: all 0.25s ease-in-out; + -webkit-transition: @il-btn-toggle-switch-transition; /* Safari */ + transition: @il-btn-toggle-switch-transition; } .il-toggle-button.on { - background: #b3b3cc; + background: @il-enabled-btn-toggle-bg; } .il-toggle-button.on .il-toggle-switch { - left: 53%; - background: #666699; + left: @il-enabled-btn-toggle-switch-position-left; + background: @il-enabled-btn-toggle-switch-color; } diff --git a/src/UI/templates/js/Button/button.js b/src/UI/templates/js/Button/button.js index bfb647e17d5e..ac173685f687 100644 --- a/src/UI/templates/js/Button/button.js +++ b/src/UI/templates/js/Button/button.js @@ -31,22 +31,31 @@ il.UI.button = il.UI.button || {}; }; /* toggle button */ - var handleToggleClick = function (event, id, on_url, on_signal, off_url, off_signal) { + var handleToggleClick = function (event, id, on_url, off_url, signals) { var b = $("#" + id); - - if (b.attr("aria-pressed") == "true") { - if (on_url != '') { - window.location = on_url; - } else { - $(on_signal.triggerer).trigger(on_signal.id, on_signal); - } - } else { - if (off_url != '') { - window.location = off_url; - } else { - $(off_signal.triggerer).trigger(off_signal.id, off_signal); + var pressed = b.attr("aria-pressed"); + for (var i = 0; i < signals.length; i++) { + var s = signals[i]; + if (s.event === "click" || + (pressed === "true" && s.event === "toggle_on") || + (pressed !== "true" && s.event === "toggle_off") + ) { + $(b).trigger(s.signal_id, { + 'id' : s.signal_id, + 'event' : s.event, + 'triggerer' : b, + 'options' : s.options}); } } + + if (pressed === "true" && on_url !== '') { + window.location = on_url; + } + + if (pressed !== "true" && off_url !== '') { + window.location = off_url; + } + //console.log('handleToggelClick: ' + id); return false; }; diff --git a/templates/default/less/variables.less b/templates/default/less/variables.less index 44c02f4bfd41..e251bf65284e 100644 --- a/templates/default/less/variables.less +++ b/templates/default/less/variables.less @@ -298,6 +298,31 @@ //** Border color of inactive buttons @il-disabled-btn-border: #e0e0e0; + +//== Toggle Buttons +// +//## + +//** The Toggle Button without the Switch +@il-btn-toggle-height: 19px; +@il-btn-toggle-padding: 25px; +@il-btn-toggle-border: 1px solid; +@il-btn-toggle-border-color: rgba(0,0,0,0.1); +@il-btn-toggle-border-radius: 40px; +@il-enabled-btn-toggle-bg: lighten(@il-enabled-btn-toggle-switch-color, 30%); +@il-disabled-btn-toggle-bg: lighten(@il-disabled-btn-toggle-switch-color, 30%); + +//** The Switch of the Toggle Button +@il-btn-toggle-switch-position-top: -4px; +@il-btn-toggle-switch-size: 25px; +@il-btn-toggle-switch-border-color: rgba(0,0,0,0.2); +@il-btn-toggle-switch-transition: all 0.25s ease-in-out; +@il-enabled-btn-toggle-switch-color: @brand-primary; +@il-enabled-btn-toggle-switch-position-left: 53%; +@il-disabled-btn-toggle-switch-color: #808080; +@il-disabled-btn-toggle-switch-position-left: -6%; + + //== Breadcrumbs // //##