mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-19 00:28:47 +02:00
N°8772 - dynamic form
This commit is contained in:
@@ -418,13 +418,8 @@ abstract class AbstractFormBlock implements IFormBlock
|
||||
/** Iterate throw output @var FormOutput $oFormOutput */
|
||||
foreach ($this->aFormOutputs as $oFormOutput) {
|
||||
|
||||
try {
|
||||
// Compute the output value
|
||||
$oFormOutput->ComputeValue($sEventType, $oData);
|
||||
}
|
||||
catch (IOException $oException) {
|
||||
IssueLog::Exception(sprintf('Unable to compute values for output %s of block %s', $oFormOutput->GetName(), $this->GetName()), $oException);
|
||||
}
|
||||
// Compute the output value
|
||||
$oFormOutput->ComputeValue($sEventType, $oData);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Symfony\Component\Form\FormView;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -26,6 +29,21 @@ class ChoiceFormType extends AbstractType
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
parent::configureOptions($resolver);
|
||||
|
||||
$resolver->setDefault('inline_display', true);
|
||||
}
|
||||
|
||||
public function buildView(FormView $view, FormInterface $form, array $options): void
|
||||
{
|
||||
parent::buildView($view, $form, $options);
|
||||
|
||||
$view->vars['inline_display'] = $options['inline_display'];
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
{
|
||||
// on preset data
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
namespace Combodo\iTop\Forms\FormBuilder;
|
||||
|
||||
use Combodo\iTop\Forms\Block\AbstractFormBlock;
|
||||
use Exception;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
@@ -131,7 +133,12 @@ class DependencyHandler
|
||||
$oFormBlock = $this->aSubBlocks[$oForm->getName()];
|
||||
|
||||
// Compute the block outputs with the data
|
||||
$oFormBlock->ComputeOutputs($sEventType, $oForm->getData());
|
||||
try{
|
||||
$oFormBlock->ComputeOutputs($sEventType, $oForm->getData());
|
||||
}
|
||||
catch(Exception $e){
|
||||
$oForm->addError(new FormError($e->getMessage()));
|
||||
}
|
||||
|
||||
// Check dependencies
|
||||
$this->CheckDependencies($oForm->getParent(), $oForm->getName(), $sEventType);
|
||||
|
||||
@@ -26,27 +26,37 @@
|
||||
{{- parent() -}}
|
||||
{%- endblock choice_widget_collapsed -%}
|
||||
|
||||
{%- block choice_widget_expanded -%}
|
||||
<div {{ block('widget_container_attributes') }}>
|
||||
{%- for child in form %}
|
||||
{{- form_widget(child) -}}
|
||||
{{- form_label(child, null, {translation_domain: choice_translation_domain, no_label_class: true}) -}}
|
||||
{% endfor -%}
|
||||
</div>
|
||||
{%- endblock choice_widget_expanded -%}
|
||||
|
||||
{%- block form_label -%}
|
||||
{%- if compound is defined and compound -%}
|
||||
{%- set no_legend_element = inline_display is defined and inline_display -%}
|
||||
{%- if compound is defined and compound and not no_legend_element -%}
|
||||
{%- set element = 'legend' -%}
|
||||
{%- else -%}
|
||||
{%- elseif no_label_class is not defined or not no_label_class -%}
|
||||
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ibo-field--label')|trim}) %}
|
||||
{%- endif -%}
|
||||
{{- parent() -}}
|
||||
{%- endblock form_label -%}
|
||||
|
||||
{#{%- block form_rows -%}#}
|
||||
{%- block form_rows -%}
|
||||
|
||||
{# {% for block in blocks %}#}
|
||||
{# <div id="block_{{ block.name }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">#}
|
||||
{# {{ block.name }} {{ block.added }}#}
|
||||
{# {% if block.added == 1 %}#}
|
||||
{# {{ form_row(form[block.name]) }}#}
|
||||
{# {% endif %}#}
|
||||
{# </div>#}
|
||||
{# {% endfor %}#}
|
||||
{% for block in blocks %}
|
||||
<div id="block_{{ block.name }}" class="ibo-field ibo-content-block ibo-block ibo-field-small">
|
||||
{{ block.name }} {{ block.added }}
|
||||
{% if block.added == 1 %}
|
||||
{{ form_row(form[block.name]) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
{#{%- endblock form_rows -%}#}
|
||||
{%- endblock form_rows -%}
|
||||
|
||||
{%- block collection_widget -%}
|
||||
{% if prototype is defined and not prototype.rendered %}
|
||||
|
||||
@@ -21,22 +21,26 @@ use ReflectionException;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||
|
||||
/**
|
||||
* Test forms block.
|
||||
*
|
||||
*/
|
||||
class Block extends ItopDataTestCase
|
||||
{
|
||||
|
||||
/**
|
||||
* Block get form type must return a class derived from Symfony form AbstractType.
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testBlockFormType()
|
||||
public function testFormBlockProvideSymfonyFormType(): void
|
||||
{
|
||||
$oChoiceBlock = new ChoiceFormBlock('choiceBlock');
|
||||
$test = new \ReflectionClass($oChoiceBlock->GetFormType());
|
||||
$this->assertTrue($test->isSubclassOf(AbstractType::class));
|
||||
|
||||
$oFormBlock = new ChoiceFormBlock('formBlock');
|
||||
$test = new \ReflectionClass($oFormBlock->GetFormType());
|
||||
$this->assertTrue($test->isSubclassOf(AbstractType::class));
|
||||
|
||||
$aFormBlocks = InterfaceDiscovery::GetInstance()->FindItopClasses(iFormBlock::class);
|
||||
foreach ($aFormBlocks as $sFormBlock) {
|
||||
$oChoiceBlock = new($sFormBlock)($sFormBlock);
|
||||
$oClass = new \ReflectionClass($oChoiceBlock->GetFormType());
|
||||
$this->assertTrue($oClass->isSubclassOf(AbstractType::class));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,7 +48,7 @@ class Block extends ItopDataTestCase
|
||||
*
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testAddBlockFromSymfonyType()
|
||||
public function testAddBlockFromSymfonyType(): void
|
||||
{
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$this->expectException(FormBlockException::class);
|
||||
@@ -54,14 +58,30 @@ class Block extends ItopDataTestCase
|
||||
/**
|
||||
* All block may contain a reference to themselves in their options
|
||||
*/
|
||||
public function testBlockOptionsContainsBlockReference()
|
||||
public function testBlockOptionsContainsBlockReference(): void
|
||||
{
|
||||
$aFormBlocks = InterfaceDiscovery::GetInstance()->FindItopClasses(iFormBlock::class);
|
||||
foreach ($aFormBlocks as $sFormBlock) {
|
||||
$oChoiceBlock = new($sFormBlock)($sFormBlock);
|
||||
$this->assertTrue($oChoiceBlock->GetOptions()['form_block'] === $oChoiceBlock);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check that a block with dependencies return true for HasDependenciesBlocks.
|
||||
*
|
||||
* @return void
|
||||
* @throws FormBlockException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testCheckDependencyState(): void
|
||||
{
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
$oFormBlock->Add('allow_age', CheckboxFormBlock::class, []);
|
||||
$oBirthdateBlock = $oFormBlock->Add('birthdate', TextFormBlock::class, [])
|
||||
->DependsOn(AbstractFormBlock::INPUT_VISIBLE, 'allow_age', CheckboxFormBlock::OUTPUT_CHECKED);
|
||||
|
||||
$this->assertTrue($oBirthdateBlock->HasDependenciesBlocks());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -71,7 +91,7 @@ class Block extends ItopDataTestCase
|
||||
* @throws FormBlockException
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function testFormBlockNotContainsDependentFields()
|
||||
public function testFormBlockNotContainsDependentFields(): void
|
||||
{
|
||||
// form with a dependent field
|
||||
$oFormBlock = new FormBlock('formBlock');
|
||||
|
||||
Reference in New Issue
Block a user