mirror of
https://github.com/Combodo/iTop.git
synced 2026-05-18 14:58:43 +02:00
form input
This commit is contained in:
@@ -55,7 +55,9 @@
|
||||
margin-top: 24px;
|
||||
}
|
||||
|
||||
.ibo-subform {
|
||||
collection-entry-element {
|
||||
margin-top: 8px;
|
||||
display: block;
|
||||
padding: 10px 10px;
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 5px;
|
||||
|
||||
@@ -18,7 +18,7 @@ class ChoicesElement extends HTMLSelectElement {
|
||||
};
|
||||
|
||||
if (this.getAttribute('data-tom-select-disable-auto-complete')) {
|
||||
options.controlInput = null;
|
||||
// options.controlInput = null;
|
||||
}
|
||||
if (this.getAttribute('data-tom-select-max-items-selected') && this.getAttribute('data-tom-select-max-items-selected') !== '') {
|
||||
options.maxItems = parseInt(this.getAttribute('data-tom-select-max-items-selected'));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
class CollectionElement extends HTMLElement {
|
||||
|
||||
#eBtn;
|
||||
#eBtnAdd;
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
@@ -11,7 +11,6 @@ class CollectionElement extends HTMLElement {
|
||||
const collectionHolder = document.querySelector('.'+e.currentTarget.dataset.collectionHolderClass);
|
||||
const item = document.createElement('div');
|
||||
|
||||
item.style.marginTop = '20px';
|
||||
item.innerHTML = collectionHolder
|
||||
.dataset
|
||||
.prototype
|
||||
@@ -22,13 +21,15 @@ class CollectionElement extends HTMLElement {
|
||||
|
||||
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);
|
||||
this.#eBtnAdd = this.querySelector('.add_item_link');
|
||||
this.#eBtnAdd.addEventListener('click', CollectionElement.addFormToCollection);
|
||||
}
|
||||
|
||||
#removeCollectionItem() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
19
js/forms/custom-elements/collection_entry.js
Normal file
19
js/forms/custom-elements/collection_entry.js
Normal file
@@ -0,0 +1,19 @@
|
||||
class CollectionEntryElement extends HTMLElement {
|
||||
|
||||
#eBtnDelete;
|
||||
|
||||
// register the custom element
|
||||
static {
|
||||
customElements.define('collection-entry-element', CollectionEntryElement);
|
||||
}
|
||||
|
||||
/** connectedCallback **/
|
||||
connectedCallback() {
|
||||
this.#eBtnDelete = this.querySelector('.remove_item_link');
|
||||
this.#eBtnDelete.addEventListener('click', this.#removeCollectionItem.bind(this));
|
||||
}
|
||||
|
||||
#removeCollectionItem(e) {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
@@ -491,6 +491,7 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => $baseDir . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeTypeChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeTypeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\LabelFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/LabelFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => $baseDir . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
@@ -525,6 +526,8 @@ return array(
|
||||
'Combodo\\iTop\\Forms\\IO\\FormOutput' => $baseDir . '/sources/Forms/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => $baseDir . '/sources/Forms/IO/Format/AbstractIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeArrayIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeIOFormat' => $baseDir . '/sources/Forms/IO/Format/AttributeTypeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => $baseDir . '/sources/Forms/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => $baseDir . '/sources/Forms/IO/Format/ClassIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\NumberIOFormat' => $baseDir . '/sources/Forms/IO/Format/NumberIOFormat.php',
|
||||
@@ -3894,5 +3897,5 @@ return array(
|
||||
'privUITransactionFile' => $baseDir . '/application/transaction.class.inc.php',
|
||||
'privUITransactionSession' => $baseDir . '/application/transaction.class.inc.php',
|
||||
'utils' => $baseDir . '/application/utils.inc.php',
|
||||
'<EFBFBD>' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
'©' => $vendorDir . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
);
|
||||
|
||||
@@ -877,6 +877,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextAreaFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextAreaFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\Base\\TextFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/Base/TextFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeTypeChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeTypeChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\AttributeValueChoiceFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/AttributeValueChoiceFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\LabelFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/LabelFormBlock.php',
|
||||
'Combodo\\iTop\\Forms\\Block\\DataModel\\OqlFormBlock' => __DIR__ . '/../..' . '/sources/Forms/Block/DataModel/OqlFormBlock.php',
|
||||
@@ -911,6 +912,8 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Forms\\IO\\FormOutput' => __DIR__ . '/../..' . '/sources/Forms/IO/FormOutput.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AbstractIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AbstractIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeArrayIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\AttributeTypeIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/AttributeTypeIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\BooleanIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/BooleanIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\ClassIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/ClassIOFormat.php',
|
||||
'Combodo\\iTop\\Forms\\IO\\Format\\NumberIOFormat' => __DIR__ . '/../..' . '/sources/Forms/IO/Format/NumberIOFormat.php',
|
||||
@@ -4280,7 +4283,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'privUITransactionFile' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
'privUITransactionSession' => __DIR__ . '/../..' . '/application/transaction.class.inc.php',
|
||||
'utils' => __DIR__ . '/../..' . '/application/utils.inc.php',
|
||||
'<EFBFBD>' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
'©' => __DIR__ . '/..' . '/symfony/cache/Traits/ValueWrapper.php',
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
|
||||
@@ -185,6 +185,7 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
|
||||
$this->LinkScriptFromAppRoot('js/forms/custom-elements/choices.js');
|
||||
$this->LinkScriptFromAppRoot('js/forms/custom-elements/oql.js');
|
||||
$this->LinkScriptFromAppRoot('js/forms/custom-elements/collection.js');
|
||||
$this->LinkScriptFromAppRoot('js/forms/custom-elements/collection_entry.js');
|
||||
|
||||
// Used by inline image, CKEditor and other places
|
||||
$this->LinkScriptFromAppRoot('node_modules/magnific-popup/dist/jquery.magnific-popup.min.js');
|
||||
|
||||
@@ -43,14 +43,15 @@ 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);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,9 +308,25 @@ abstract class AbstractFormBlock implements IFormBlock
|
||||
* @return $this
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
public function DependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): AbstractFormBlock
|
||||
public function InputDependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): AbstractFormBlock
|
||||
{
|
||||
$this->oIORegister->DependsOn($sInputName, $sOutputBlockName, $sOutputName);
|
||||
$this->oIORegister->InputDependsOn($sInputName, $sOutputBlockName, $sOutputName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set an input value.
|
||||
*
|
||||
* @param string $sInputName
|
||||
* @param mixed $oValue
|
||||
*
|
||||
* @return $this
|
||||
* @throws RegisterException
|
||||
*/
|
||||
public function SetInputValue(string $sInputName, mixed $oValue): AbstractFormBlock
|
||||
{
|
||||
$this->oIORegister->GetInput($sInputName)->SetValue(AbstractFormIO::EVENT_FORM_STATIC, $oValue);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -322,9 +339,9 @@ abstract class AbstractFormBlock implements IFormBlock
|
||||
* @return $this
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
public function DependsOnParent(string $sInputName, string $sParentInputName): AbstractFormBlock
|
||||
public function InputDependsOnParent(string $sInputName, string $sParentInputName): AbstractFormBlock
|
||||
{
|
||||
$this->oIORegister->DependsOnParent($sInputName, $sParentInputName);
|
||||
$this->oIORegister->InputDependsOnParent($sInputName, $sParentInputName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -337,9 +354,9 @@ abstract class AbstractFormBlock implements IFormBlock
|
||||
* @return $this
|
||||
* @throws FormBlockException
|
||||
*/
|
||||
public function ImpactParent(string $sOutputName, string $sParentOutputName): AbstractFormBlock
|
||||
public function OutputImpactParent(string $sOutputName, string $sParentOutputName): AbstractFormBlock
|
||||
{
|
||||
$this->oIORegister->ImpactParent($sOutputName, $sParentOutputName);
|
||||
$this->oIORegister->OutputImpactParent($sOutputName, $sParentOutputName);
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ class CollectionBlock extends AbstractTypeFormBlock
|
||||
|
||||
public function EntryDependsOnParent(string $sInputName, string $sParentInputName): AbstractFormBlock
|
||||
{
|
||||
$this->oPrototypeBlock->DependsOnParent($sInputName, $sParentInputName);
|
||||
$this->oPrototypeBlock->InputDependsOnParent($sInputName, $sParentInputName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\DataModel;
|
||||
|
||||
use Combodo\iTop\Core\AttributeDefinition\AttributeEnum;
|
||||
use Combodo\iTop\Forms\Block\FormBlockException;
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeTypeArrayIOFormat;
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeTypeIOFormat;
|
||||
use Combodo\iTop\Forms\Register\RegisterException;
|
||||
use Combodo\iTop\Service\DependencyInjection\DIException;
|
||||
use Combodo\iTop\Service\DependencyInjection\DIService;
|
||||
@@ -29,6 +32,7 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
{
|
||||
// inputs
|
||||
public const INPUT_CLASS_NAME = 'input_class_name';
|
||||
public const INPUT_ATTRIBUTE_TYPE = 'input_attribute_type';
|
||||
|
||||
// outputs
|
||||
public const OUTPUT_ATTRIBUTE = 'output_attribute';
|
||||
@@ -46,6 +50,7 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
{
|
||||
parent::RegisterIO($oIORegister);
|
||||
$oIORegister->AddInput(self::INPUT_CLASS_NAME, ClassIOFormat::class);
|
||||
$oIORegister->AddInput(self::INPUT_ATTRIBUTE_TYPE, AttributeTypeIOFormat::class);
|
||||
$oIORegister->AddOutput(self::OUTPUT_ATTRIBUTE, AttributeIOFormat::class);
|
||||
}
|
||||
|
||||
@@ -62,6 +67,7 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
|
||||
// Get class name
|
||||
$sClass = strval($this->GetInputValue(self::INPUT_CLASS_NAME));
|
||||
$sAttType = $this->GetInputValue(self::INPUT_ATTRIBUTE_TYPE)->sAttributeType;
|
||||
|
||||
// Empty class => no choices
|
||||
if (utils::IsNullOrEmptyString($sClass)) {
|
||||
@@ -71,7 +77,7 @@ class AttributeChoiceFormBlock extends ChoiceFormBlock
|
||||
|
||||
/** List attributes @var ModelReflection $oModelReflection */
|
||||
$oModelReflection = DIService::GetInstance()->GetService('ModelReflection');
|
||||
$aAttributeCodes = array_keys($oModelReflection->ListAttributes($sClass));
|
||||
$aAttributeCodes = array_keys($oModelReflection->ListAttributes($sClass, $sAttType));
|
||||
$aAttributes = [];
|
||||
foreach ($aAttributeCodes as $sAttCode) {
|
||||
$sLabel = $oModelReflection->GetLabel($sClass, $sAttCode);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2025 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Forms\Block\DataModel;
|
||||
|
||||
use AttributeClass;
|
||||
use Combodo\iTop\Core\AttributeDefinition\AttributeBoolean;
|
||||
use Combodo\iTop\Core\AttributeDefinition\AttributeDate;
|
||||
use Combodo\iTop\Core\AttributeDefinition\AttributeEnum;
|
||||
use Combodo\iTop\Core\AttributeDefinition\AttributeString;
|
||||
use Combodo\iTop\Forms\IO\Format\AttributeTypeIOFormat;
|
||||
use Combodo\iTop\Forms\Block\Base\ChoiceFormBlock;
|
||||
use Combodo\iTop\Forms\Register\IORegister;
|
||||
use Combodo\iTop\Forms\Register\OptionsRegister;
|
||||
|
||||
/**
|
||||
* A block to choose an attribute type.
|
||||
*
|
||||
* @package Combodo\iTop\Forms\Block\DataModel
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class AttributeTypeChoiceFormBlock extends ChoiceFormBlock
|
||||
{
|
||||
// outputs
|
||||
public const OUTPUT_ATTRIBUTE_TYPE = 'output_type';
|
||||
|
||||
/** @inheritdoc */
|
||||
protected function RegisterOptions(OptionsRegister $oOptionsRegister): void
|
||||
{
|
||||
parent::RegisterOptions($oOptionsRegister);
|
||||
$oOptionsRegister->SetOption('placeholder', 'Select a type...');
|
||||
$oOptionsRegister->SetOption('choices', [
|
||||
'enum' => AttributeEnum::class,
|
||||
'string' => AttributeString::class,
|
||||
'date' => AttributeDate::class,
|
||||
'boolean' => AttributeBoolean::class,
|
||||
'class' => AttributeClass::class,
|
||||
]);
|
||||
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
protected function RegisterIO(IORegister $oIORegister): void
|
||||
{
|
||||
parent::RegisterIO($oIORegister);
|
||||
$oIORegister->AddOutput(self::OUTPUT_ATTRIBUTE_TYPE, AttributeTypeIOFormat::class);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,7 +7,9 @@
|
||||
|
||||
namespace Combodo\iTop\Forms\FormType;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Combodo\iTop\Forms\Block\Base\FormBlock;
|
||||
use Combodo\iTop\Forms\FormBuilder\DependencyMap;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
|
||||
/**
|
||||
@@ -57,7 +59,7 @@ class FormTypeHelper
|
||||
$oMap = $oBlockTurboTrigger->GetParent()->GetDependenciesMap();
|
||||
|
||||
// Add impacted blocks
|
||||
$aImpacted = $oMap->GetBlocksImpactedBy($oBlockTurboTrigger->GetName());
|
||||
$aImpacted = static::GetImpactedByRecursive($oMap, $oBlockTurboTrigger);
|
||||
foreach ($aImpacted as $oImpactedBlock) {
|
||||
$sName = $sParentName.'_'.$oImpactedBlock->GetName();
|
||||
if ($oParent->has($oImpactedBlock->GetName())) {
|
||||
@@ -74,6 +76,21 @@ class FormTypeHelper
|
||||
];
|
||||
}
|
||||
|
||||
private static function GetImpactedByRecursive(DependencyMap $oMap, AbstractFormBlock $oBLock): ?array
|
||||
{
|
||||
$aImpacted = $oMap->GetBlocksImpactedBy($oBLock->GetName());
|
||||
if ($aImpacted !== null) {
|
||||
foreach ($aImpacted as $oImpactedBlock) {
|
||||
$aRecursiveImpacted = static::GetImpactedByRecursive($oMap, $oImpactedBlock);
|
||||
if ($aRecursiveImpacted !== null) {
|
||||
$aImpacted = array_merge($aImpacted, $aRecursiveImpacted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aImpacted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FormInterface $oForm
|
||||
* @param string $sBlockTurboTriggerName
|
||||
|
||||
@@ -19,6 +19,10 @@ use Symfony\Component\Form\FormEvents;
|
||||
*/
|
||||
class AbstractFormIO
|
||||
{
|
||||
public const EVENT_POST_SET_DATA = FormEvents::POST_SET_DATA;
|
||||
public const EVENT_POST_SUBMIT = FormEvents::POST_SUBMIT;
|
||||
public const EVENT_FORM_STATIC = 'form.static';
|
||||
|
||||
/** @var AbstractFormBlock The owner block */
|
||||
private AbstractFormBlock $oOwnerBlock;
|
||||
|
||||
@@ -43,7 +47,7 @@ class AbstractFormIO
|
||||
* @param string $sName name of the IO
|
||||
* @param string $sType type of the IO
|
||||
*
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function __construct(string $sName, string $sType, AbstractFormBlock $oOwnerBlock)
|
||||
{
|
||||
@@ -81,7 +85,7 @@ class AbstractFormIO
|
||||
* @param string $sName
|
||||
*
|
||||
* @return self
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function SetName(string $sName): self
|
||||
{
|
||||
@@ -204,6 +208,9 @@ class AbstractFormIO
|
||||
*/
|
||||
private function Value(): mixed
|
||||
{
|
||||
if (array_key_exists('form.static', $this->aValues)) {
|
||||
return $this->aValues['form.static'];
|
||||
}
|
||||
if (array_key_exists(FormEvents::POST_SUBMIT, $this->aValues)) {
|
||||
return $this->aValues[FormEvents::POST_SUBMIT];
|
||||
}
|
||||
@@ -220,7 +227,7 @@ class AbstractFormIO
|
||||
* @param FormInput $oDestinationIO
|
||||
*
|
||||
* @return FormBinding
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function BindToInput(FormInput $oDestinationIO): FormBinding
|
||||
{
|
||||
@@ -236,7 +243,7 @@ class AbstractFormIO
|
||||
* @param FormBinding $oFormBinding
|
||||
*
|
||||
* @return void
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException when already bound
|
||||
* @throws FormBlockIOException when already bound
|
||||
*/
|
||||
public function Attach(FormBinding $oFormBinding): void
|
||||
{
|
||||
|
||||
@@ -29,7 +29,10 @@ class FormOutput extends AbstractFormIO
|
||||
*
|
||||
* @param string $sName
|
||||
* @param string $sType
|
||||
* @param AbstractFormBlock $oOwnerBlock
|
||||
* @param AbstractConverter|null $oConverter
|
||||
*
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function __construct(string $sName, string $sType, AbstractFormBlock $oOwnerBlock, AbstractConverter $oConverter = null)
|
||||
{
|
||||
@@ -91,7 +94,7 @@ class FormOutput extends AbstractFormIO
|
||||
* @param FormOutput $oDestinationIO
|
||||
*
|
||||
* @return FormBinding
|
||||
* @throws \Combodo\iTop\Forms\IO\FormBlockIOException
|
||||
* @throws FormBlockIOException
|
||||
*/
|
||||
public function BindToOutput(FormOutput $oDestinationIO): FormBinding
|
||||
{
|
||||
|
||||
34
sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php
Normal file
34
sources/Forms/IO/Format/AttributeTypeArrayIOFormat.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
use Combodo\iTop\Service\DependencyInjection\DIService;
|
||||
use Combodo\iTop\Forms\IO\FormBlockIOException;
|
||||
|
||||
/**
|
||||
* Attribute type array IO format.
|
||||
*
|
||||
* @package Combodo\iTop\Forms\IO\Format
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class AttributeTypeArrayIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public array $aClasses;
|
||||
|
||||
/**
|
||||
*/
|
||||
public function __construct(array $aClasses)
|
||||
{
|
||||
$this->aClasses = $aClasses;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return json_encode($this->aClasses);
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return json_encode($this->aClasses);
|
||||
}
|
||||
}
|
||||
29
sources/Forms/IO/Format/AttributeTypeIOFormat.php
Normal file
29
sources/Forms/IO/Format/AttributeTypeIOFormat.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\Forms\IO\Format;
|
||||
|
||||
/**
|
||||
* Attribute type IO format.
|
||||
*
|
||||
* @package Combodo\iTop\Forms\IO\Format
|
||||
* @since 3.3.0
|
||||
*/
|
||||
class AttributeTypeIOFormat extends AbstractIOFormat
|
||||
{
|
||||
public string $sAttributeType;
|
||||
|
||||
public function __construct(string $sAttributeType)
|
||||
{
|
||||
$this->sAttributeType = $sAttributeType;
|
||||
}
|
||||
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->sAttributeType;
|
||||
}
|
||||
|
||||
public function jsonSerialize(): mixed
|
||||
{
|
||||
return $this->sAttributeType;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +74,7 @@ class IORegister
|
||||
$oBlockOutput = $oOutputBlock->GetOutput($sOutputName);
|
||||
|
||||
$this->AddInput($sName, $oBlockOutput->GetDataType());
|
||||
$this->DependsOn($sName, $sOutputBlockName, $sOutputName);
|
||||
$this->InputDependsOn($sName, $sOutputBlockName, $sOutputName);
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ class IORegister
|
||||
* @throws FormBlockIOException
|
||||
* @throws RegisterException
|
||||
*/
|
||||
public function DependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): self
|
||||
public function InputDependsOn(string $sInputName, string $sOutputBlockName, string $sOutputName): self
|
||||
{
|
||||
$oOutputBlock = $this->oFormBlock->GetParent()?->Get($sOutputBlockName);
|
||||
if (is_null($oOutputBlock)) {
|
||||
@@ -115,7 +115,7 @@ class IORegister
|
||||
* @throws FormBlockIOException
|
||||
* @throws RegisterException
|
||||
*/
|
||||
public function ImpactParent(string $sOutputName, string $sParentOutputName): self
|
||||
public function OutputImpactParent(string $sOutputName, string $sParentOutputName): self
|
||||
{
|
||||
$oFormOutput = $this->GetOutput($sOutputName);
|
||||
$oParentFormOutput = $this->oFormBlock->GetParent()->GetOutput($sParentOutputName);
|
||||
@@ -359,7 +359,7 @@ class IORegister
|
||||
* @throws FormBlockIOException
|
||||
* @throws RegisterException
|
||||
*/
|
||||
public function DependsOnParent(string $sInputName, string $sParentInputName): self
|
||||
public function InputDependsOnParent(string $sInputName, string $sParentInputName): self
|
||||
{
|
||||
$oFormInput = $this->GetInput($sInputName);
|
||||
$oParentFormInput = $this->oFormBlock->GetParent()->GetInput($sParentInputName);
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
{%- block choice_widget_collapsed -%}
|
||||
{% set attr = attr|merge({class: (attr.class|default('') ~ ' ibo-input')|trim}) %}
|
||||
<select is="choices-element" class="field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete ui-autocomplete-input" style="display: none"
|
||||
<select is="choices-element" class="field_autocomplete ibo-input ibo-input-select ibo-input-select-autocomplete ui-autocomplete-input"
|
||||
{{ block('widget_attributes') }}
|
||||
{% if multiple %} multiple="multiple" {% endif %}
|
||||
{% if max_items_selected is defined %} data-tom-select-max-items-selected="{{ max_items_selected }}" {% endif %}
|
||||
@@ -79,16 +79,30 @@
|
||||
{%- 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 %}
|
||||
{{- block('form_widget') -}}
|
||||
{% if allow_add %}
|
||||
<div style="margin-top: 20px;">
|
||||
<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>
|
||||
{% set deleteBtn = '<button type="button" class="remove_item_link ibo-button ibo-is-regular ibo-is-danger">Supprimer</button>' %}
|
||||
{%- set prototype_html = '<collection-entry-element>' ~ form_widget(prototype) ~ ' ' ~ deleteBtn ~'</collection-entry-element>' -%}
|
||||
{%- set attr = attr|merge({'data-prototype': prototype_html, 'class': name, 'data-index': form|length > 0 ? form|last.vars.name + 1 : 0 }) -%}
|
||||
{% endif %}
|
||||
|
||||
<collection-element {{ block('widget_container_attributes') }}>
|
||||
|
||||
{% for child in form %}
|
||||
<collection-entry-element>
|
||||
{{ form_widget(child) }}
|
||||
{% if allow_delete %}
|
||||
<button type="button" class="remove_item_link ibo-button ibo-is-regular ibo-is-danger">Supprimer</button>
|
||||
{% endif %}
|
||||
</collection-entry-element>
|
||||
{% endfor %}
|
||||
|
||||
{% if allow_add %}
|
||||
<div style="margin-top: 20px;">
|
||||
<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 -%}
|
||||
@@ -130,4 +144,3 @@
|
||||
</button>
|
||||
</div>
|
||||
{%- endblock oql_form_row -%}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ class BlockTest extends AbstractFormsTest
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$oFormBlock->Add('allow_age', CheckboxFormBlock::class, []);
|
||||
$oBirthdateBlock = $oFormBlock->Add('birthdate', TextFormBlock::class, [])
|
||||
->DependsOn(AbstractTypeFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
->InputDependsOn(AbstractTypeFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
|
||||
$this->assertTrue($oBirthdateBlock->HasDependenciesBlocks());
|
||||
}
|
||||
@@ -100,7 +100,7 @@ class BlockTest extends AbstractFormsTest
|
||||
$oFormBlock->Add('lastname', TextFormBlock::class, []);
|
||||
$oFormBlock->Add('allow_age', CheckboxFormBlock::class, []);
|
||||
$oFormBlock->Add('birthdate', TextFormBlock::class, [])
|
||||
->DependsOn(AbstractTypeFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
->InputDependsOn(AbstractTypeFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
|
||||
// form builder
|
||||
$oFormFactoryBuilder = Forms::createFormFactoryBuilder();
|
||||
|
||||
@@ -81,9 +81,9 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$oSubForm->AddInput('input_from_C', StringIOFormat::class);
|
||||
$oSubForm->AddInput('unbound_input', StringIOFormat::class);
|
||||
|
||||
$this->GivenIORegister($oSubForm)->DependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->GivenIORegister($oSubForm)->DependsOn('input_from_B', 'SubFormB', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
$this->GivenIORegister($oSubForm)->DependsOn('input_from_C', 'SubFormC', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->GivenIORegister($oSubForm)->InputDependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->GivenIORegister($oSubForm)->InputDependsOn('input_from_B', 'SubFormB', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
$this->GivenIORegister($oSubForm)->InputDependsOn('input_from_C', 'SubFormC', TextFormBlock::OUTPUT_TEXT);
|
||||
|
||||
$aBoundInputs = $this->GivenIORegister($oSubForm)->GetBoundInputs();
|
||||
$this->assertCount(3, $aBoundInputs);
|
||||
@@ -96,7 +96,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$oSubFormA = $this->GivenSubFormBlock($this->oFormBlock, 'SubFormA', TextFormBlock::class);
|
||||
$oIORegisterA = $this->GivenIORegister($oSubFormA);
|
||||
|
||||
$oIORegisterA->ImpactParent(TextFormBlock::OUTPUT_TEXT, 'output');
|
||||
$oIORegisterA->OutputImpactParent(TextFormBlock::OUTPUT_TEXT, 'output');
|
||||
|
||||
$this->assertCount(1, $this->oIORegister->GetBoundOutputs());
|
||||
}
|
||||
@@ -119,7 +119,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$oSubFormA = $this->GivenSubFormBlock($this->oFormBlock, 'SubFormA', TextFormBlock::class);
|
||||
$oIORegisterA = $this->GivenIORegister($oSubFormA);
|
||||
|
||||
$oIORegisterA->ImpactParent(TextFormBlock::OUTPUT_TEXT, 'output');
|
||||
$oIORegisterA->OutputImpactParent(TextFormBlock::OUTPUT_TEXT, 'output');
|
||||
|
||||
$this->assertTrue($this->oFormBlock->GetOutput('output')->IsBound());
|
||||
}
|
||||
@@ -145,7 +145,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
|
||||
$this->expectException(RegisterException::class);
|
||||
|
||||
$this->oIORegister->DependsOn('non_existing_input', 'OtherBlock', 'test_output');
|
||||
$this->oIORegister->InputDependsOn('non_existing_input', 'OtherBlock', 'test_output');
|
||||
}
|
||||
|
||||
public function testDependingOnNonExistingOutputThrowsException(): void
|
||||
@@ -153,7 +153,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$this->oIORegister->AddInput('test_input', StringIOFormat::class);
|
||||
|
||||
$this->expectException(RegisterException::class);
|
||||
$this->oIORegister->DependsOn('test_input', 'OtherBlock', 'non_existing_output');
|
||||
$this->oIORegister->InputDependsOn('test_input', 'OtherBlock', 'non_existing_output');
|
||||
}
|
||||
|
||||
public function testDependingOnNonExistingBlockThrowsException(): void
|
||||
@@ -162,7 +162,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$this->oIORegister->AddOutput('test_output', StringIOFormat::class);
|
||||
|
||||
$this->expectException(RegisterException::class);
|
||||
$this->oIORegister->DependsOn('test_input', 'UnknownBlock', 'test');
|
||||
$this->oIORegister->InputDependsOn('test_input', 'UnknownBlock', 'test');
|
||||
}
|
||||
|
||||
public function testHasDependenciesBlocks(): void
|
||||
@@ -172,7 +172,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$oSubForm = $this->GivenSubFormBlock($this->oFormBlock, 'SubForm', TextFormBlock::class);
|
||||
$oSubForm->AddInput('input_from_A', StringIOFormat::class);
|
||||
|
||||
$this->GivenIORegister($oSubForm)->DependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->GivenIORegister($oSubForm)->InputDependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->assertTrue($this->GivenIORegister($oSubForm)->HasDependenciesBlocks());
|
||||
|
||||
$this->assertFalse($this->oIORegister->HasDependenciesBlocks());
|
||||
@@ -185,7 +185,7 @@ class IORegisterTest extends AbstractFormsTest
|
||||
$oSubForm = $this->GivenSubFormBlock($this->oFormBlock, 'SubForm', TextFormBlock::class);
|
||||
$oSubForm->AddInput('input_from_A', StringIOFormat::class);
|
||||
|
||||
$this->GivenIORegister($oSubForm)->DependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->GivenIORegister($oSubForm)->InputDependsOn('input_from_A', 'SubFormA', TextFormBlock::OUTPUT_TEXT);
|
||||
$this->assertFalse($this->GivenIORegister($oSubForm)->ImpactDependentsBlocks());
|
||||
|
||||
$this->assertTrue($this->GivenIORegister($oSubFormA)->ImpactDependentsBlocks());
|
||||
|
||||
Reference in New Issue
Block a user