collections

This commit is contained in:
Benjamin Dalsass
2025-12-03 17:47:22 +01:00
parent b1129f19d7
commit 4620710f5a
8 changed files with 60 additions and 40 deletions

View File

@@ -54,3 +54,9 @@
.ibo-field legend{
margin-top: 24px;
}
.ibo-subform {
padding: 10px 10px;
background-color: #f5f5f5;
border-radius: 5px;
}

View File

@@ -0,0 +1,34 @@
class CollectionElement extends HTMLElement {
#eBtn;
// register the custom element
static {
customElements.define('collection-element', CollectionElement);
}
static addFormToCollection(e) {
const collectionHolder = document.querySelector('.'+e.currentTarget.dataset.collectionHolderClass);
const item = document.createElement('div');
item.style.marginTop = '20px';
item.innerHTML = collectionHolder
.dataset
.prototype
.replace(
/__name__/g,
collectionHolder.dataset.index
);
collectionHolder.appendChild(item);
collectionHolder.dataset.index++;
console.log(collectionHolder.dataset.index);
}
/** connectedCallback **/
connectedCallback() {
this.#eBtn = this.querySelector('.add_item_link');
this.#eBtn.addEventListener('click', CollectionElement.addFormToCollection);
}
}

View File

@@ -26,20 +26,3 @@ function isCheckbox (element) {
&& element.getAttribute('type') === 'checkbox'
}
function addFormToCollection(e) {
const collectionHolder = document.querySelector('.' + e.currentTarget.dataset.collectionHolderClass);
const item = document.createElement('div');
item.style.marginTop = '20px';
item.innerHTML = collectionHolder
.dataset
.prototype
.replace(
/__name__/g,
collectionHolder.dataset.index
);
collectionHolder.appendChild(item);
collectionHolder.dataset.index++;
console.log(collectionHolder.dataset.index);
}

View File

@@ -184,6 +184,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
$this->LinkScriptFromAppRoot('node_modules/tom-select/dist/js/tom-select.complete.min.js');
$this->LinkScriptFromAppRoot('js/forms/custom-elements/choices.js');
$this->LinkScriptFromAppRoot('js/forms/custom-elements/oql.js');
$this->LinkScriptFromAppRoot('js/forms/custom-elements/collection.js');
// Used by inline image, CKEditor and other places
$this->LinkScriptFromAppRoot('node_modules/magnific-popup/dist/jquery.magnific-popup.min.js');

View File

@@ -16,6 +16,7 @@ use Combodo\iTop\Forms\IO\FormOutput;
use Combodo\iTop\Forms\Register\IORegister;
use Combodo\iTop\Forms\Register\OptionsRegister;
use Combodo\iTop\Forms\Register\RegisterException;
use Combodo\iTop\Forms\Block\Base\CollectionBlock;
/**
* Abstract form block.
@@ -25,8 +26,8 @@ use Combodo\iTop\Forms\Register\RegisterException;
*/
abstract class AbstractFormBlock implements IFormBlock
{
/** @var null|FormBlock */
private ?FormBlock $oParent = null;
/** @var null|FormBlock|CollectionBlock */
private FormBlock|CollectionBlock|null $oParent = null;
/** @var OptionsRegister */
private OptionsRegister $oOptionsRegister;
@@ -42,14 +43,14 @@ abstract class AbstractFormBlock implements IFormBlock
*/
public function __construct(private readonly string $sName, array $aOptions = [])
{
// Register IO
$this->RegisterIO($this->oIORegister = new IORegister($this));
$this->AfterIORegistered($this->oIORegister);
// Register options
$this->RegisterOptions($this->oOptionsRegister = new OptionsRegister());
$this->SetOptions($aOptions);
$this->AfterOptionsRegistered($this->oOptionsRegister);
// Register IO
$this->RegisterIO($this->oIORegister = new IORegister($this));
$this->AfterIORegistered($this->oIORegister);
}
/**
@@ -65,11 +66,11 @@ abstract class AbstractFormBlock implements IFormBlock
/**
* Set the parent block.
*
* @param FormBlock $oParent
* @param FormBlock|CollectionBlock $oParent
*
* @return void
*/
public function SetParent(FormBlock $oParent): void
public function SetParent(FormBlock|CollectionBlock $oParent): void
{
$this->oParent = $oParent;
}
@@ -77,9 +78,9 @@ abstract class AbstractFormBlock implements IFormBlock
/**
* Get the parent block.
*
* @return FormBlock|null
* @return FormBlock|CollectionBlock|null
*/
public function GetParent(): ?FormBlock
public function GetParent(): FormBlock|CollectionBlock|null
{
return $this->oParent;
}

View File

@@ -25,9 +25,6 @@ class CollectionBlock extends AbstractTypeFormBlock
// Inputs
public const INPUT_CLASS_NAME = 'input_class_name';
/** @var FormBlock block */
protected AbstractTypeFormBlock $oPrototypeBlock;
/** @inheritdoc */
public function GetFormType(): string
{
@@ -56,15 +53,12 @@ class CollectionBlock extends AbstractTypeFormBlock
{
parent::RegisterOptions($oOptionsRegister);
$oOptionsRegister->SetOption('entry_block', null, false);
$oOptionsRegister->SetOption('prototype', true);
$oOptionsRegister->SetOption('allow_add', true);
$oOptionsRegister->SetOption('prototype_options', [
'label' => false,
]);
// not type options
$oOptionsRegister->SetOption('block_entry_type', FormBlock::class, false);
$oOptionsRegister->SetOption('block_entry_options', [], false);
}
/** @inheritdoc */
@@ -72,13 +66,11 @@ class CollectionBlock extends AbstractTypeFormBlock
{
parent::AfterOptionsRegistered($oOptionsRegister);
$sBlockEntryType = $this->GetOption('block_entry_type');
$sBlockEntryOptions = $this->GetOption('block_entry_options');
$this->oPrototypeBlock = new ($sBlockEntryType)('prototype', $sBlockEntryOptions);
$oBlockEntryType = $this->GetOption('entry_block');
try {
$oOptionsRegister->SetOption('entry_type', $this->oPrototypeBlock->GetFormType());
$oOptionsRegister->SetOption('entry_options', $this->oPrototypeBlock->GetOptions());
$oOptionsRegister->SetOption('entry_type', $oBlockEntryType->GetFormType());
$oOptionsRegister->SetOption('entry_options', $oBlockEntryType->GetOptions());
} catch (RegisterException $e) {
}

View File

@@ -79,6 +79,7 @@
{%- endblock form_rows -%}
{%- block collection_widget -%}
<collection-element>
{% if prototype is defined and not prototype.rendered %}
{%- set attr = attr|merge({'data-prototype': form_row(prototype), 'class': name, 'data-index': form|length > 0 ? form|last.vars.name + 1 : 0 }) -%}
{% endif %}
@@ -88,6 +89,8 @@
<button type="button" class="add_item_link ibo-button ibo-button ibo-is-regular " data-collection-holder-class="{{ name }}">{{ button_label|dict_s }}</button>
</div>
{% endif %}
</collection-element>
{%- endblock collection_widget -%}
{%- block form_label_content -%}

View File

@@ -17,4 +17,4 @@
{% UITurboStream Replace { sTarget: current_form.vars.id} %}
{{ form_widget(current_form) }}
{% EndUITurboStream %}
{% endif %}
{% endif %}