From 301e69ef1d497338ff7612136ee6c390dff0f58a Mon Sep 17 00:00:00 2001 From: Johannes Meyer Date: Fri, 3 May 2024 16:41:02 +0200 Subject: [PATCH] TermInput: Allow to enable read-only terms and style them --- asset/css/compat.less | 6 +++- asset/css/search-base.less | 26 ++++++++++++++++ src/FormElement/TermInput.php | 34 ++++++++++++++++++++- src/FormElement/TermInput/TermContainer.php | 19 ++++++++---- 4 files changed, 77 insertions(+), 8 deletions(-) diff --git a/asset/css/compat.less b/asset/css/compat.less index 1188c7e9..0a4426d1 100644 --- a/asset/css/compat.less +++ b/asset/css/compat.less @@ -80,9 +80,13 @@ form.icinga-form .control-group { width: 0; } - input[type="text"] { + input { flex: unset; width: 100%; + + &[type="button"] { + background-color: @default-input-bg; + } } } } diff --git a/asset/css/search-base.less b/asset/css/search-base.less index e4af764b..608db5c8 100644 --- a/asset/css/search-base.less +++ b/asset/css/search-base.less @@ -209,6 +209,32 @@ outline-width: 3px; outline-offset: ~"calc(-@{labelPad} + 3px)"; } + + &.read-only { + label { + position: relative; + + input[type="button"] { + padding-left: 1.5em; + + &:disabled { + cursor: default; + } + + + i { + position: absolute; + display: none; + top: .5em; + left: .5em; + } + } + + input[type="button"]:not(:disabled):hover + i, + input[type="button"]:not(:disabled):focus + i { + display: revert; + } + } + } } .search-suggestions { diff --git a/src/FormElement/TermInput.php b/src/FormElement/TermInput.php index 184be1da..9310ffe6 100644 --- a/src/FormElement/TermInput.php +++ b/src/FormElement/TermInput.php @@ -40,6 +40,9 @@ class TermInput extends FieldsetElement /** @var bool Whether term direction is vertical */ protected $verticalTermDirection = false; + /** @var bool Whether registered terms are read-only */ + protected $readOnly = false; + /** @var array Changes to transmit to the client */ protected $changes = []; @@ -103,6 +106,30 @@ public function getTermDirection(): ?string return $this->verticalTermDirection ? 'vertical' : null; } + /** + * Set whether registered terms are read-only + * + * @param bool $state + * + * @return $this + */ + public function setReadOnly(bool $state = true): self + { + $this->readOnly = $state; + + return $this; + } + + /** + * Get whether registered terms are read-only + * + * @return bool + */ + public function getReadOnly(): bool + { + return $this->readOnly; + } + /** * Set terms * @@ -415,6 +442,7 @@ public function getValueAttribute() 'data-with-multi-completion' => true, 'data-no-auto-submit-on-remove' => true, 'data-term-direction' => $this->getTermDirection(), + 'data-read-only-terms' => $this->getReadOnly(), 'data-data-input' => '#' . $dataInputId, 'data-term-input' => '#' . $termInputId, 'data-term-container' => '#' . $termContainer->getAttribute('id')->getValue(), @@ -436,7 +464,11 @@ public function getValueAttribute() $mainInput->prependWrapper((new HtmlElement( 'div', - Attributes::create(['class' => ['term-input-area', $this->getTermDirection()]]), + Attributes::create(['class' => [ + 'term-input-area', + $this->getTermDirection(), + $this->getReadOnly() ? 'read-only' : null + ]]), $termContainer, new HtmlElement('label', null, $mainInput) ))); diff --git a/src/FormElement/TermInput/TermContainer.php b/src/FormElement/TermInput/TermContainer.php index c5a614cd..b7b61dac 100644 --- a/src/FormElement/TermInput/TermContainer.php +++ b/src/FormElement/TermInput/TermContainer.php @@ -6,6 +6,7 @@ use ipl\Html\BaseHtmlElement; use ipl\Html\HtmlElement; use ipl\Web\FormElement\TermInput; +use ipl\Web\Widget\Icon; class TermContainer extends BaseHtmlElement { @@ -28,27 +29,33 @@ public function __construct(TermInput $input) protected function assemble() { + $inputType = $this->input->getReadOnly() ? 'button' : 'text'; foreach ($this->input->getTerms() as $i => $term) { - $label = $term->getLabel() ?: $term->getSearchValue(); + $value = $term->getLabel() ?: $term->getSearchValue(); - $this->addHtml(new HtmlElement( + $label = new HtmlElement( 'label', Attributes::create([ 'class' => $term->getClass(), 'data-search' => $term->getSearchValue(), - 'data-label' => $label, + 'data-label' => $value, 'data-index' => $i ]), new HtmlElement( 'input', Attributes::create([ - 'type' => 'text', - 'value' => $label, + 'type' => $inputType, + 'value' => $value, 'pattern' => $term->getPattern(), 'data-invalid-msg' => $term->getMessage() ]) ) - )); + ); + if ($inputType === 'button') { + $label->addHtml(new Icon('trash')); + } + + $this->addHtml($label); } } }