N°8772 - WIP dependencies - Does not work yet

This commit is contained in:
Eric Espie
2025-11-04 09:05:29 +01:00
parent 0909ddfb3a
commit 5a1f6ffde9
7 changed files with 60 additions and 24 deletions

14
js/forms/forms.js Normal file
View File

@@ -0,0 +1,14 @@
/*
* @copyright Copyright (C) 2010-2025 Combodo SARL
* @license http://opensource.org/licenses/AGPL-3.0
*/
function triggerTurbo(el) {
let sFormName = el.form.getAttribute("name");
el.form.querySelector(`[name="${sFormName}[_turbo_trigger]"]`).value = el.getAttribute('name');
el.form.setAttribute('novalidate', true);
el.form.requestSubmit();
console.log('Auto submitting form due to change in field ' + el.getAttribute('name'));
}

View File

@@ -164,6 +164,8 @@ class iTopWebPage extends NiceWebPage implements iTabbedPage
{
parent::InitializeLinkedScripts();
$this->LinkScriptFromAppRoot('js/forms/forms.js');
// Used by forms
$this->LinkScriptFromAppRoot('js/leave_handler.js');

View File

@@ -13,8 +13,6 @@ use Combodo\iTop\Forms\Block\IO\Format\RawFormat;
use Combodo\iTop\Forms\Block\IO\FormInput;
use Combodo\iTop\Forms\Block\IO\FormOutput;
use Combodo\iTop\Forms\IFormBlock;
use IssueLog;
use Symfony\Component\Filesystem\Exception\IOException;
/**
* Abstract form block.
@@ -104,9 +102,9 @@ abstract class AbstractFormBlock implements IFormBlock
/**
* Get the parent block.
*
* @return FormBlock
* @return FormBlock|null
*/
public function GetParent(): FormBlock
public function GetParent(): ?FormBlock
{
return $this->oParent;
}
@@ -121,6 +119,15 @@ abstract class AbstractFormBlock implements IFormBlock
return $this->sName;
}
public function GetIdentifier(): string
{
$sParentName = $this->GetParent()?->GetIdentifier();
if (is_null($sParentName)) {
return $this->GetName();
}
return $sParentName.'_'.$this->sName;
}
/**
* Return the form block options.
* Options will be passed to FormType for building.

View File

@@ -9,6 +9,7 @@ namespace Combodo\iTop\Forms\Block\Base;
use Combodo\iTop\Forms\Block\AbstractFormBlock;
use Combodo\iTop\Forms\Block\FormBlockException;
use Combodo\iTop\Forms\Block\FormType\FormType;
use Combodo\iTop\Forms\FormBuilder\DependencyMap;
use Combodo\iTop\Forms\FormsException;
use Exception;
use ReflectionClass;
@@ -19,8 +20,9 @@ use ReflectionClass;
*/
class FormBlock extends AbstractFormBlock
{
/** @var array children blocks */
/** @var AbstractFormBlock[] children blocks */
private array $aChildrenBlocks = [];
public ?DependencyMap $oDependencyMap = null;
/**
* Constructor.
@@ -56,7 +58,7 @@ class FormBlock extends AbstractFormBlock
$aUserOptions['compound'] = true;
$aUserOptions['attr'] = [
'class' => 'form'
'class' => 'form',
];
}
@@ -118,4 +120,20 @@ class FormBlock extends AbstractFormBlock
}
public function GetSubFormBlock(string $sBlockTurboTriggerName): ?AbstractFormBlock
{
$oBlock = $this;
if (preg_match_all('/\[(?<level>[^\[]+)\]/', $sBlockTurboTriggerName, $aMatches)) {
foreach ($aMatches['level'] as $level) {
$oBlock = $oBlock->Get($level);
}
}
return $oBlock;
}
public function GetDependenciesMap(): ?DependencyMap
{
return $this->oDependencyMap;
}
}

View File

@@ -161,8 +161,8 @@ class DependencyMap
public function GetImpacted(string $sBlockName): array
{
$aImpacted = [];
if (array_key_exists($sBlockName, $this->aOutputToInputsMap)) {
foreach ($this->aOutputToInputsMap[$sBlockName] as $aBindings) {
if (array_key_exists($sBlockName, $this->aBindingsOutputToInput)) {
foreach ($this->aBindingsOutputToInput[$sBlockName] as $aBindings) {
foreach ($aBindings as $oBinding) {
$oDestBlock = $oBinding->oDestinationIO->GetOwnerBlock();
$aImpacted[] = $oDestBlock;

View File

@@ -13,6 +13,7 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormConfigInterface;
use Symfony\Component\Form\FormFactoryInterface;
@@ -87,6 +88,11 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
// Create a dependency handler if needed
if (count($aBlocksWithDependencies) > 0) {
$this->oDependencyHandler = new DependencyHandler($this->builder->getName(), $oFormBlock, $this, $this->aChildren, $aBlocksWithDependencies);
$oFormBlock->oDependencyMap = $this->oDependencyHandler->GetMap();
if (is_null($oFormBlock->GetParent())) {
// Insert a hidden type to save the place
$this->builder->add('_turbo_trigger', HiddenType::class, ['prevent_form_build' => true]);
}
}
}
@@ -101,26 +107,15 @@ class FormBuilder implements FormBuilderInterface, IteratorAggregate
{
// Has dependencies blocks
if ($oSubFormBlock->HasDependenciesBlocks()) {
// // Insert a hidden type to save the place
// $this->builder->add($oSubFormBlock->GetName(), HiddenType::class, [
// 'form_block' => $oSubFormBlock,
// 'prevent_form_build' => true,
//// 'mapped' => false,
//// 'disabled' => true,
// ]);
return true;
} else {
if (!$oSubFormBlock->HasDependenciesBlocks()) {
// Directly insert the block corresponding form type
$this->add($oSubFormBlock->GetName(), $oSubFormBlock->GetFormType(), $oSubFormBlock->GetOptions());
$oSubFormBlock->SetAdded(true);
return false;
}
return true;
}
/**

View File

@@ -5,7 +5,7 @@
{%- block widget_attributes -%}
{{- parent() -}}
{% if trigger_form_submit_on_modify %}
onChange="this.form.setAttribute('novalidate', true); this.form.requestSubmit();console.log('Auto submitting form due to change in field {{ full_name }}');"
onChange="triggerTurbo(this);"
{% endif %}
{%- endblock widget_attributes -%}
@@ -48,7 +48,7 @@
{%- block form_rows -%}
{% for block in blocks %}
<div id="block_{{ block.name }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">
<div id="block_{{ block.identifier }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">
{{ block.name }} {{ block.added }}
{% if block.added == 1 %}
{{ form_row(form[block.name]) }}