mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-20 17:18:51 +02:00
N°7063 - Forms SDK - Add Symfony forms component
error forms issue
This commit is contained in:
@@ -55,3 +55,25 @@
|
||||
.form_interval_horizontal > div{
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.form-compound-fieldset{
|
||||
padding: 8px;
|
||||
border-radius: 10px;
|
||||
border: 1px dashed lightgrey;
|
||||
}
|
||||
|
||||
|
||||
.form-layout-row{
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
.form-layout-column{
|
||||
margin: 10px;
|
||||
}
|
||||
.form-layout-column:first-child{
|
||||
margin-left: 0px;
|
||||
}
|
||||
.form-layout-column:last-child{
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
|
||||
@@ -400,6 +400,7 @@ return array(
|
||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Controller\\TestController' => $baseDir . '/sources/FormImplementation/Controller/TestController.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Dto\\CountDto' => $baseDir . '/sources/FormImplementation/Dto/CountDto.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Dto\\ObjectSearchDto' => $baseDir . '/sources/FormImplementation/Dto/ObjectSearchDto.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\FormHelper' => $baseDir . '/sources/FormImplementation/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\SelectDataProvider' => $baseDir . '/sources/FormImplementation/Helper/SelectDataProvider.php',
|
||||
@@ -412,9 +413,10 @@ return array(
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormFactoryBuilderTrait' => $baseDir . '/sources/FormSDK/Service/FormFactoryBuilderTrait.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormManager' => $baseDir . '/sources/FormSDK/Service/FormManager.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\SymfonyBridge' => $baseDir . '/sources/FormSDK/Symfony/SymfonyBridge.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Compound\\FieldsetType' => $baseDir . '/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Compound\\FormObjectType' => $baseDir . '/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\AbstractLayoutType' => $baseDir . '/sources/FormSDK/Symfony/Type/Layout/LayoutType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\ColumnType' => $baseDir . '/sources/FormSDK/Symfony/Type/Layout/ColumnType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\FieldsetType' => $baseDir . '/sources/FormSDK/Symfony/Type/Layout/FieldsetType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\RowType' => $baseDir . '/sources/FormSDK/Symfony/Type/Layout/RowType.php',
|
||||
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => $baseDir . '/sources/Form/Field/AbstractSimpleField.php',
|
||||
'Combodo\\iTop\\Form\\Field\\BlobField' => $baseDir . '/sources/Form/Field/BlobField.php',
|
||||
|
||||
@@ -809,6 +809,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Controller\\TestController' => __DIR__ . '/../..' . '/sources/FormImplementation/Controller/TestController.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Dto\\CountDto' => __DIR__ . '/../..' . '/sources/FormImplementation/Dto/CountDto.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Dto\\ObjectSearchDto' => __DIR__ . '/../..' . '/sources/FormImplementation/Dto/ObjectSearchDto.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\FormHelper' => __DIR__ . '/../..' . '/sources/FormImplementation/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\SelectDataProvider' => __DIR__ . '/../..' . '/sources/FormImplementation/Helper/SelectDataProvider.php',
|
||||
@@ -821,9 +822,10 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormFactoryBuilderTrait' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FormFactoryBuilderTrait.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormManager' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FormManager.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\SymfonyBridge' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/SymfonyBridge.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Compound\\FieldsetType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Compound/FieldsetType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Compound\\FormObjectType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\AbstractLayoutType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Layout/LayoutType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\ColumnType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Layout/ColumnType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\FieldsetType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Layout/FieldsetType.php',
|
||||
'Combodo\\iTop\\FormSDK\\Symfony\\Type\\Layout\\RowType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Layout/RowType.php',
|
||||
'Combodo\\iTop\\Form\\Field\\AbstractSimpleField' => __DIR__ . '/../..' . '/sources/Form/Field/AbstractSimpleField.php',
|
||||
'Combodo\\iTop\\Form\\Field\\BlobField' => __DIR__ . '/../..' . '/sources/Form/Field/BlobField.php',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '75fde4c9a3fb4b46ae8765e961d0f590bdad199b',
|
||||
'reference' => '00f241e4cf314d4190bedeba80de9ec12461b958',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '75fde4c9a3fb4b46ae8765e961d0f590bdad199b',
|
||||
'reference' => '00f241e4cf314d4190bedeba80de9ec12461b958',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
34
sources/FormImplementation/Dto/CountDto.php
Normal file
34
sources/FormImplementation/Dto/CountDto.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormImplementation\Dto;
|
||||
|
||||
use ArrayAccess;
|
||||
|
||||
class CountDto implements ArrayAccess
|
||||
{
|
||||
public function __construct(
|
||||
public int $count1 = 11,
|
||||
public int $count2 = 22,
|
||||
public int $count3 = 33,
|
||||
) {
|
||||
}
|
||||
|
||||
public function offsetExists($offset) : bool
|
||||
{
|
||||
return property_exists($this, $offset);
|
||||
}
|
||||
|
||||
public function offsetGet($offset) : mixed
|
||||
{
|
||||
return $this->$offset;
|
||||
}
|
||||
public function offsetSet($offset, $value) : void
|
||||
{
|
||||
$this->$offset = $value;
|
||||
}
|
||||
|
||||
public function offsetUnset($offset) : void
|
||||
{
|
||||
unset($this->$offset);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,9 @@
|
||||
namespace Combodo\iTop\FormImplementation\Helper;
|
||||
|
||||
use Combodo\iTop\Controller\AbstractAppController;
|
||||
use Combodo\iTop\FormImplementation\Dto\CountDto;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Service\FormManager;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
@@ -30,6 +33,23 @@ class FormHelper
|
||||
// create a factory
|
||||
$oFormFactory = $oFormManager->CreateFactory();
|
||||
|
||||
// form data
|
||||
$aData = [
|
||||
'city' => 'Autun',
|
||||
'tel' => '+33(6) 35 57 48 77',
|
||||
'birthday' => new DateTime('1979/06/27'),
|
||||
'count' => 10,
|
||||
'counts' => ['count1' => 10, 'count2' => 20, 'count3' => 30],
|
||||
'counts2' => new CountDto(),
|
||||
'interval' => ['days' => '12', 'hours' => '13', 'years' => '10', 'months' => '6', 'minutes' => '0', 'seconds' => '0', 'weeks' => '3'],
|
||||
'blog' => 'Your <b>story</b>',
|
||||
'notify' => true,
|
||||
'language' => 'FR FR',
|
||||
'mode' => '1',
|
||||
'options' => ['0', '2','4']
|
||||
];
|
||||
$oFormFactory->SetData($aData);
|
||||
|
||||
// add X person forms...
|
||||
for($i = 0 ; $i < self::$PERSON_COUNT ; $i++){
|
||||
|
||||
@@ -37,7 +57,7 @@ class FormHelper
|
||||
$oPerson = MetaModel::GetObject('Person', $i+1);
|
||||
|
||||
// create object adapter
|
||||
$oObjectPlugin = $oFormFactory->CreateObjectAdapter($oPerson, true);
|
||||
$oObjectPlugin = $oFormFactory->CreateObjectAdapter($oPerson, false);
|
||||
$oObjectPlugin->AddAttribute('name');
|
||||
$oObjectPlugin->AddAttribute('mobile_phone');
|
||||
}
|
||||
@@ -47,27 +67,51 @@ class FormHelper
|
||||
'label' => 'Ma ville',
|
||||
'help' => 'This is where you live',
|
||||
'constraints' => new Length(['min' => 3])
|
||||
], 'Autun');
|
||||
]);
|
||||
|
||||
// tel - text with pattern
|
||||
$oFormFactory->AddTextField('tel', [
|
||||
'label' => 'Tel',
|
||||
'constraints' => new Regex(['pattern' => '/\+33\(\d\) \d\d \d\d \d\d \d\d/'], null, '+{33}(0) 00 00 00 00'),
|
||||
'required' => false
|
||||
], '+33(6) 35 57 48 77');
|
||||
]);
|
||||
|
||||
// birthday - date
|
||||
$oFormFactory->AddDateField('birthday', [
|
||||
'label' => 'Anniversaire',
|
||||
'widget' => 'single_text',
|
||||
'required' => false
|
||||
], new DateTime('1979/06/27'));
|
||||
]);
|
||||
|
||||
// count - number
|
||||
$oFormFactory->AddNumberField('count', [
|
||||
'label' => 'Compteur',
|
||||
'required' => false
|
||||
], 10);
|
||||
]);
|
||||
|
||||
// counts - fieldset
|
||||
$oCount1 = new FormFieldDescription('count1', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oCount2 = new FormFieldDescription('count2', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oCount3 = new FormFieldDescription('count3', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oFormFactory->AddFieldSet('counts', [
|
||||
'label' => 'Compteurs',
|
||||
'required' => false,
|
||||
'fields' => [
|
||||
$oCount1, $oCount2, $oCount3
|
||||
]
|
||||
]);
|
||||
|
||||
// counts - fieldset alternative
|
||||
$oCount1 = new FormFieldDescription('count1', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oCount2 = new FormFieldDescription('count2', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oCount3 = new FormFieldDescription('count3', FormFieldTypeEnumeration::NUMBER, []);
|
||||
$oFormFactory->AddFieldSet('counts2', [
|
||||
'label' => 'Compteurs',
|
||||
'required' => false,
|
||||
'fields' => [
|
||||
$oCount1, $oCount2, $oCount3 // OR $oData
|
||||
]
|
||||
]);
|
||||
|
||||
// interval - duration
|
||||
$oFormFactory->AddDurationField('interval', [
|
||||
@@ -80,24 +124,24 @@ class FormHelper
|
||||
'attr' => [
|
||||
'class' => 'form_interval_horizontal'
|
||||
]
|
||||
], ['days' => '12', 'hours' => '13', 'years' => '10', 'months' => '6', 'minutes' => '0', 'seconds' => '0', 'weeks' => '3']);
|
||||
]);
|
||||
|
||||
// ready
|
||||
$oFormFactory->AddSwitchField('notify', [
|
||||
'label' => 'Veuillez m\'avertir en cas de changement',
|
||||
], true);
|
||||
]);
|
||||
|
||||
// blog - date
|
||||
$oFormFactory->AddAreaField('blog', [
|
||||
'label' => 'Blog',
|
||||
'required' => false
|
||||
], 'Your story');
|
||||
]);
|
||||
|
||||
// language - select with static data
|
||||
$oFormFactory->AddSelectField('language', [
|
||||
'label' => 'Ma langue',
|
||||
'choices' => SelectDataProvider::GetApplicationLanguages()
|
||||
], 'FR FR');
|
||||
]);
|
||||
|
||||
// dog - select with ajax API
|
||||
$oFormFactory->AddSelectAjaxField('dog', [
|
||||
@@ -136,10 +180,10 @@ class FormHelper
|
||||
'label_attr' => [
|
||||
'class' => 'radio-inline'
|
||||
]
|
||||
], '1');
|
||||
]);
|
||||
|
||||
// options - select with static data
|
||||
$oFormFactory->AddSelectField('option', [
|
||||
$oFormFactory->AddSelectField('options', [
|
||||
'label' => 'Mes options',
|
||||
'choices' => SelectDataProvider::GetOptions(),
|
||||
'expanded' => true,
|
||||
@@ -147,7 +191,7 @@ class FormHelper
|
||||
'label_attr' => [
|
||||
'class' => 'checkbox-inline'
|
||||
]
|
||||
], ['0', '2','4']);
|
||||
]);
|
||||
|
||||
// layout description
|
||||
$oFormFactory->SetLayoutDescription([
|
||||
|
||||
@@ -33,8 +33,8 @@ enum FormFieldTypeEnumeration : string
|
||||
case DATE = 'DATE';
|
||||
case SELECT = 'SELECT';
|
||||
case SWITCH = 'SWITCH';
|
||||
case DB_OBJECT = 'DB_OBJECT';
|
||||
case DURATION = 'DURATION';
|
||||
case FIELDSET = 'FIELDSET';
|
||||
|
||||
/**
|
||||
* Return available options.
|
||||
@@ -44,7 +44,7 @@ enum FormFieldTypeEnumeration : string
|
||||
public function GetAvailableOptions() : array
|
||||
{
|
||||
// global options
|
||||
$aOptions = ['required', 'disabled', 'attr', 'label', 'label_attr', 'help'];
|
||||
$aOptions = ['required', 'disabled', 'attr', 'label', 'label_attr', 'help', 'inherit_data'];
|
||||
|
||||
// specific options
|
||||
$test = match ($this) {
|
||||
@@ -60,7 +60,7 @@ enum FormFieldTypeEnumeration : string
|
||||
FormFieldTypeEnumeration::DURATION => array_merge($aOptions,
|
||||
['input', 'with_minutes', 'with_seconds', 'with_weeks', 'with_days']
|
||||
),
|
||||
FormFieldTypeEnumeration::DB_OBJECT => array_merge($aOptions,
|
||||
FormFieldTypeEnumeration::FIELDSET => array_merge($aOptions,
|
||||
['fields']
|
||||
),
|
||||
default => $aOptions,
|
||||
|
||||
@@ -192,9 +192,9 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
}
|
||||
|
||||
if($this->bGroup){
|
||||
$oGroupDescriptions = new FormFieldDescription($this->GetIdentifier(), FormFieldTypeEnumeration::DB_OBJECT, [
|
||||
$oGroupDescriptions = new FormFieldDescription($this->GetIdentifier(), FormFieldTypeEnumeration::FIELDSET, [
|
||||
'fields' => $aFieldsDescriptions,
|
||||
'label' => $this->GetLabel()
|
||||
'label' => $this->GetLabel(),
|
||||
]);
|
||||
return [$this->GetIdentifier() => $oGroupDescriptions];
|
||||
}
|
||||
|
||||
@@ -49,8 +49,11 @@ class FormFactory
|
||||
/** @var array $aFieldsDescriptions form types descriptions */
|
||||
private array $aFieldsDescriptions = [];
|
||||
|
||||
/** @var array $aFieldsData form data */
|
||||
private array $aFieldsData = [];
|
||||
/** @var mixed $oFieldsData form data */
|
||||
private mixed $oFieldsData = [];
|
||||
|
||||
/** @var array $aLayoutDecription description of the layout */
|
||||
private array $aLayoutDecription;
|
||||
|
||||
/** builder */
|
||||
use FormFactoryBuilderTrait;
|
||||
@@ -70,27 +73,34 @@ class FormFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Return fields descriptions and data arrays.
|
||||
* Return fields descriptions.
|
||||
*
|
||||
* @return array{descriptions:array, data:array}
|
||||
* @return array{fields_descriptions:array, layout_description:array}
|
||||
*/
|
||||
public function GetFieldsDescriptionsAndData() : array
|
||||
public function GetFieldsDescriptions() : array
|
||||
{
|
||||
// prepare data
|
||||
$aResult = [
|
||||
'descriptions' => $this->aFieldsDescriptions,
|
||||
'data' => $this->aFieldsData,
|
||||
];
|
||||
$aResult = $this->aFieldsDescriptions;
|
||||
|
||||
|
||||
// merge each adapter data...
|
||||
foreach ($this->GetAllAdapters() as $oAdapter){
|
||||
$aResult['descriptions'] = array_merge($aResult['descriptions'], $oAdapter->GetFieldsDescriptions());
|
||||
$aResult['data'] = array_merge($aResult['data'], $oAdapter->GetFieldsData());
|
||||
$aResult = array_merge($aResult, $oAdapter->GetFieldsDescriptions());
|
||||
}
|
||||
|
||||
return $aResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return layout description.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function GetLayoutDescription() : array
|
||||
{
|
||||
return $this->aLayoutDecription;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an object adapter.
|
||||
*
|
||||
@@ -130,6 +140,43 @@ class FormFactory
|
||||
return $this->aAdapters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set layout description.
|
||||
*
|
||||
* @param array $aLayoutDescription
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function SetLayoutDescription(array $aLayoutDescription)
|
||||
{
|
||||
$this->aLayoutDecription = $aLayoutDescription;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function SetData(mixed $oData) : void
|
||||
{
|
||||
$this->oFieldsData = $oData;
|
||||
}
|
||||
|
||||
/***
|
||||
* @return array
|
||||
*/
|
||||
public function GetData() : mixed
|
||||
{
|
||||
$aData = $this->oFieldsData;
|
||||
|
||||
foreach ($this->GetAllAdapters() as $adapter){
|
||||
$aData = array_merge($aData, $adapter->GetFieldsData());
|
||||
}
|
||||
|
||||
return $aData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create form.
|
||||
*
|
||||
@@ -138,8 +185,8 @@ class FormFactory
|
||||
*/
|
||||
public function CreateForm(?string $sName = null) : mixed
|
||||
{
|
||||
['descriptions' => $aDescriptions, 'data' => $aData] = $this->GetFieldsDescriptionsAndData();
|
||||
return $this->oSymfonyBridge->CreateForm($aDescriptions, $aData, $sName);
|
||||
$aFieldsDescriptions = $this->GetFieldsDescriptions();
|
||||
return $this->oSymfonyBridge->CreateForm($aFieldsDescriptions, $this->GetData(), $sName, $this->GetLayoutDescription());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,11 +16,10 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddTextField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddTextField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
// test widget for regex constraint
|
||||
if(array_key_exists('constraints', $aOptions)){
|
||||
@@ -40,7 +39,6 @@ trait FormFactoryBuilderTrait
|
||||
}
|
||||
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::TEXT, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -50,16 +48,12 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddNumberField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddNumberField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
// $aOptions['property_path'] = $sKey;
|
||||
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::NUMBER, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -69,11 +63,10 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddAreaField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddAreaField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$aOptions = array_merge([
|
||||
'attr' => [
|
||||
@@ -83,7 +76,6 @@ trait FormFactoryBuilderTrait
|
||||
], $aOptions);
|
||||
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::AREA, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -93,14 +85,12 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddDateField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddDateField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::DATE, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -110,14 +100,12 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddDurationField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddDurationField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::DURATION, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -127,14 +115,12 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSelectField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddSelectField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::SELECT, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -146,11 +132,10 @@ trait FormFactoryBuilderTrait
|
||||
* @param array $aOptions
|
||||
* @param array $aAjaxOptions
|
||||
* @param array $aAjaxData
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return \Combodo\iTop\FormSDK\Service\FormFactory
|
||||
*/
|
||||
public function AddSelectAjaxField(string $sKey, array $aOptions, array $aAjaxOptions, array $aAjaxData = [], mixed $oData = null) : FormFactory
|
||||
public function AddSelectAjaxField(string $sKey, array $aOptions, array $aAjaxOptions, array $aAjaxData = []) : FormFactory
|
||||
{
|
||||
// merge ajax options
|
||||
$aAjaxOptions = array_merge([
|
||||
@@ -184,7 +169,7 @@ trait FormFactoryBuilderTrait
|
||||
// }),
|
||||
], $aOptions);
|
||||
|
||||
return $this->AddSelectField($sKey, $aOptions, $oData);
|
||||
return $this->AddSelectField($sKey, $aOptions);
|
||||
}
|
||||
|
||||
|
||||
@@ -198,11 +183,10 @@ trait FormFactoryBuilderTrait
|
||||
* @param array $aFieldsToLoad
|
||||
* @param string $sSearch
|
||||
* @param int $iAjaxThershold
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return \Combodo\iTop\FormSDK\Service\FormFactory
|
||||
*/
|
||||
public function AddSelectOqlField(string $sKey, array $aOptions, string $sObjectClass, string $sOql, array $aFieldsToLoad, string $sSearch, int $iAjaxThershold, mixed $oData = null) : FormFactory
|
||||
public function AddSelectOqlField(string $sKey, array $aOptions, string $sObjectClass, string $sOql, array $aFieldsToLoad, string $sSearch, int $iAjaxThershold) : FormFactory
|
||||
{
|
||||
$aAjaxData = [
|
||||
'class' => $sObjectClass,
|
||||
@@ -219,7 +203,7 @@ trait FormFactoryBuilderTrait
|
||||
'threshold' => $iAjaxThershold,
|
||||
'configuration' => 'OQL'
|
||||
];
|
||||
return $this->AddSelectAjaxField($sKey, $aOptions, $aAjaxOptions, $aAjaxData, $oData);
|
||||
return $this->AddSelectAjaxField($sKey, $aOptions, $aAjaxOptions, $aAjaxData);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,18 +211,32 @@ trait FormFactoryBuilderTrait
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSwitchField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
public function AddSwitchField(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$aOptions = array_merge([
|
||||
'label_attr' => ['class' => 'checkbox-switch'],
|
||||
], $aOptions);
|
||||
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::SWITCH, $aOptions);
|
||||
$this->aFieldsData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add fieldset.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddFieldSet(string $sKey, array $aOptions) : FormFactory
|
||||
{
|
||||
$this->aFieldsDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::FIELDSET, $aOptions);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -19,9 +19,12 @@
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony;
|
||||
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Compound\FormObjectType;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Compound\FieldsetType;
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Compound\FormObjectType;
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Layout\ColumnType;
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Layout\RowType;
|
||||
use LogAPI;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
@@ -100,7 +103,7 @@ class SymfonyBridge
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::DB_OBJECT:
|
||||
case FormFieldTypeEnumeration::FIELDSET:
|
||||
$aOptions = $oFormDescription->GetOptions();
|
||||
$aFields = [];
|
||||
foreach ($aOptions['fields'] as $oChildFormDescription){
|
||||
@@ -110,7 +113,7 @@ class SymfonyBridge
|
||||
$aOptions['fields'] = $aFields;
|
||||
return [
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => FormObjectType::class,
|
||||
'type' => FieldsetType::class,
|
||||
'options' => $aOptions
|
||||
];
|
||||
|
||||
@@ -137,43 +140,51 @@ class SymfonyBridge
|
||||
* Create Symfony form.
|
||||
*
|
||||
* @param array $aDescriptions
|
||||
* @param array $aData
|
||||
* @param mixed $oData
|
||||
* @param string|null $sName
|
||||
* @param array|null $aLayout
|
||||
*
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
*/
|
||||
public function CreateForm(array $aDescriptions, array $aData, ?string $sName = null): FormInterface
|
||||
public function CreateForm(array $aDescriptions, mixed $oData, ?string $sName = null, array $aLayout = []): FormInterface
|
||||
{
|
||||
// create Symfony form builder
|
||||
if($sName !== null){
|
||||
$oFormBuilder = $this->oFormFactory->createNamedBuilder($sName, FormType::class, $aData);
|
||||
$oFormBuilder = $this->oFormFactory->createNamedBuilder($sName, FormType::class, $oData);
|
||||
}
|
||||
else{
|
||||
$oFormBuilder = $this->oFormFactory->createBuilder(FormType::class, $aData);
|
||||
$oFormBuilder = $this->oFormFactory->createBuilder(FormType::class, $oData);
|
||||
}
|
||||
|
||||
// iterate throw descriptions...
|
||||
foreach ($aDescriptions as $oFormDescription){
|
||||
// transform fields descriptions...
|
||||
$aSymfonyTypesDeclaration = [];
|
||||
foreach ($aDescriptions as $sKey => $oFormDescription){
|
||||
$aSymfonyTypesDeclaration[$sKey] = $this->ToSymfonyFormType($oFormDescription);
|
||||
}
|
||||
|
||||
// symfony form type description
|
||||
$aSymfony = $this->ToSymfonyFormType($oFormDescription);
|
||||
// create layout types
|
||||
['types' => $aItems] = $this->CreateLayoutTypes($aLayout, $oFormBuilder, $aSymfonyTypesDeclaration);
|
||||
$oTest = array_merge($aItems, $aSymfonyTypesDeclaration);
|
||||
|
||||
// add symfony types to builder...
|
||||
foreach ($oTest as $oSymfonyTypeDeclaration){
|
||||
|
||||
// add type to form
|
||||
$oFormBuilder->add(
|
||||
$aSymfony['name'],
|
||||
$aSymfony['type'],
|
||||
$aSymfony['options']
|
||||
$oSymfonyTypeDeclaration['name'],
|
||||
$oSymfonyTypeDeclaration['type'],
|
||||
$oSymfonyTypeDeclaration['options']
|
||||
);
|
||||
|
||||
/**
|
||||
* Allow choices to be loaded client side via ajax.
|
||||
* without this, field value needs to be part of initial choices that may be empty.
|
||||
* Need reflexion because, value can be hacked with invalid value without extra validation.
|
||||
* without this, field value needs to be part of initial choices that may be empty.
|
||||
* Need reflexion because, value can be hacked with invalid value without validation.
|
||||
* @see https://symfony.com/doc/current/reference/forms/types/choice.html#choice-loader
|
||||
* @see https://itecnote.com/tecnote/php-disable-backend-validation-for-choice-field-in-symfony-2-type/
|
||||
*/
|
||||
if($aSymfony['type'] === ChoiceType::class){
|
||||
$oFormBuilder->get($aSymfony['name'])->resetViewTransformers();
|
||||
*/
|
||||
if($oSymfonyTypeDeclaration['type'] === ChoiceType::class){
|
||||
$oFormBuilder->get($oSymfonyTypeDeclaration['name'])->resetViewTransformers();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -181,4 +192,62 @@ class SymfonyBridge
|
||||
return $oFormBuilder->getForm();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $aLayout
|
||||
* @param $oFormBuilder
|
||||
* @param array $aDescriptions
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function CreateLayoutTypes($aLayout, $oFormBuilder, array &$aDescriptions){
|
||||
|
||||
$aResult = [];
|
||||
$sClasses = '';
|
||||
|
||||
foreach ($aLayout as $sKey => $oLayoutElement)
|
||||
{
|
||||
if($sKey === 'css_classes'){
|
||||
$sClasses = $oLayoutElement;
|
||||
}
|
||||
else if(str_starts_with($sKey, 'row__')){
|
||||
$aResult[$sKey] = $this->CreateLayoutContainerType($oLayoutElement, $oFormBuilder, $sKey, RowType::class, $aDescriptions);
|
||||
}
|
||||
else if(str_starts_with($sKey, 'column__')){
|
||||
$aResult[$sKey] = $this->CreateLayoutContainerType($oLayoutElement, $oFormBuilder, $sKey, ColumnType::class, $aDescriptions);
|
||||
}
|
||||
else if(str_starts_with($sKey, 'fieldset__')){
|
||||
$aResult[$sKey] = $this->CreateLayoutContainerType($oLayoutElement, $oFormBuilder, $sKey, FieldsetType::class, $aDescriptions);
|
||||
}
|
||||
else {
|
||||
if (array_key_exists($oLayoutElement, $aDescriptions)) {
|
||||
$aResult[$oLayoutElement] = $aDescriptions[$oLayoutElement];
|
||||
unset($aDescriptions[$oLayoutElement]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'types' => $aResult,
|
||||
'css_classes' => $sClasses
|
||||
];
|
||||
}
|
||||
|
||||
private function CreateLayoutContainerType($oLayoutElement, $oFormBuilder, $sKey, $oType, &$aDescriptions)
|
||||
{
|
||||
['types' => $aItems, 'css_classes' => $sCssClasses] = $this->CreateLayoutTypes($oLayoutElement, $oFormBuilder, $aDescriptions);
|
||||
|
||||
return [
|
||||
'name' => $sKey,
|
||||
'type' => $oType,
|
||||
'options' => [
|
||||
'fields' => $aItems,
|
||||
'attr' => [
|
||||
'class' => $sCssClasses
|
||||
],
|
||||
'inherit_data' => true
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
72
sources/FormSDK/Symfony/Type/Compound/FieldsetType.php
Normal file
72
sources/FormSDK/Symfony/Type/Compound/FieldsetType.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony\Type\Compound;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* Type representing a fieldset;
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class FieldsetType extends AbstractType
|
||||
{
|
||||
|
||||
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildForm(FormBuilderInterface $builder, array $options) : void
|
||||
{
|
||||
|
||||
|
||||
foreach ($options['fields'] as $oField){
|
||||
$builder->add($oField['name'], $oField['type'], $oField['options']);
|
||||
}
|
||||
}
|
||||
|
||||
private function handleRow(FormBuilderInterface $builder, array $aData){
|
||||
|
||||
}
|
||||
|
||||
private function handleColumn(FormBuilderInterface $builder, array $aData){
|
||||
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'fields' => [],
|
||||
'view' => [],
|
||||
]);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function getParent(): string
|
||||
{
|
||||
return FormType::class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -34,41 +34,12 @@ use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
class FormObjectType extends AbstractType
|
||||
{
|
||||
|
||||
/*
|
||||
* View Definition.
|
||||
*
|
||||
* [
|
||||
* 'row' => [
|
||||
* 'col' => [
|
||||
* 'description' => [
|
||||
* 'label' => '',
|
||||
* 'css_classes' => ''
|
||||
* ],
|
||||
* 'items' => ['name', 'birthday']
|
||||
* 'fieldset' => ['address', 'city', 'country']
|
||||
* ]
|
||||
* ]
|
||||
* ]
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildForm(FormBuilderInterface $builder, array $options) : void
|
||||
{
|
||||
foreach ($options['view'] as $oItem) {
|
||||
|
||||
if($oItem === 'row'){
|
||||
$this->handleRow();
|
||||
}
|
||||
else if($oItem === 'col'){
|
||||
$this->handleColumn();
|
||||
}
|
||||
else{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
foreach ($options['fields'] as $oField){
|
||||
$builder->add($oField['name'], $oField['type'], $oField['options']);
|
||||
@@ -90,7 +61,7 @@ class FormObjectType extends AbstractType
|
||||
'fields' => [],
|
||||
'view' => [],
|
||||
'attr' => [
|
||||
'class' => ''
|
||||
'class' => 'form-object-row'
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
43
sources/FormSDK/Symfony/Type/Layout/ColumnType.php
Normal file
43
sources/FormSDK/Symfony/Type/Layout/ColumnType.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony\Type\Layout;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* Type representing a layout column;
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class ColumnType extends AbstractType
|
||||
{
|
||||
|
||||
/** @inheritdoc */
|
||||
public function getParent(): string
|
||||
{
|
||||
return LayoutType::class;
|
||||
}
|
||||
|
||||
}
|
||||
62
sources/FormSDK/Symfony/Type/Layout/LayoutType.php
Normal file
62
sources/FormSDK/Symfony/Type/Layout/LayoutType.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony\Type\Layout;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* Type representing an abstract layout type;
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class LayoutType extends AbstractType
|
||||
{
|
||||
|
||||
/** @inheritdoc */
|
||||
public function buildForm(FormBuilderInterface $builder, array $options) : void
|
||||
{
|
||||
|
||||
foreach ($options['fields'] as $oField){
|
||||
$builder->add($oField['name'], $oField['type'], $oField['options']);
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'fields' => [],
|
||||
'view' => [],
|
||||
'inherit_data' => true // this type is abstract and used for grouping
|
||||
]);
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function getParent(): string
|
||||
{
|
||||
return FormType::class;
|
||||
}
|
||||
|
||||
}
|
||||
43
sources/FormSDK/Symfony/Type/Layout/RowType.php
Normal file
43
sources/FormSDK/Symfony/Type/Layout/RowType.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
/*
|
||||
* Copyright (C) 2013-2023 Combodo SARL
|
||||
*
|
||||
* This file is part of iTop.
|
||||
*
|
||||
* iTop is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* iTop is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony\Type\Layout;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
/**
|
||||
* Type representing a layout row;
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class RowType extends AbstractType
|
||||
{
|
||||
|
||||
/** @inheritdoc */
|
||||
public function getParent(): string
|
||||
{
|
||||
return LayoutType::class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,8 +31,14 @@
|
||||
|
||||
{%- endblock form_label -%}
|
||||
|
||||
{%- block form_object_row -%}
|
||||
{%- set row_attr = row_attr|merge({class: 'mb-3 form-object-row'}) -%}
|
||||
{{ form_row(form, {'row_attr': row_attr}) }}
|
||||
{%- endblock form_object_row -%}
|
||||
{%- block row_row -%}
|
||||
{{ form_widget(form, {'attr' : {'class' : attr.class|default('') ~ ' form-layout-row'}}) }}
|
||||
{%- endblock row_row -%}
|
||||
|
||||
{%- block column_row -%}
|
||||
{{ form_widget(form, {'attr' : {'class' : attr.class|default('') ~ ' form-layout-column'}}) }}
|
||||
{%- endblock column_row -%}
|
||||
|
||||
{%- block fieldset_row -%}
|
||||
{{ form_row(form, {'attr' : {'class' : attr.class|default('') ~ ' form-compound-fieldset'}}) }}
|
||||
{%- endblock fieldset_row -%}
|
||||
|
||||
Reference in New Issue
Block a user