mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-19 00:28:47 +02:00
N°7063 - Forms SDK - Add Symfony forms component
error forms issue
This commit is contained in:
@@ -1,7 +1,11 @@
|
||||
html{
|
||||
font-family: "Montserrat";
|
||||
}
|
||||
/**
|
||||
* Widgets Factory.
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
|
||||
/* debug purpose */
|
||||
.form-type-pictograms{
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
@@ -11,56 +15,31 @@ html{
|
||||
padding: 0px 5px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.form-type-pictograms i{
|
||||
width: 15px;
|
||||
}
|
||||
|
||||
.form-object legend{
|
||||
font-weight: bold;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
.form-object{
|
||||
border: 1px lightgrey dashed;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.complete .pattern:after{
|
||||
.complete .form-type-pictograms .pattern:after{
|
||||
content: '\f00c';
|
||||
font-family: "Font Awesome 6 Free";
|
||||
font-weight: 900;
|
||||
background-color: #20b220;
|
||||
border-radius: 50%;
|
||||
font-size: 9px;
|
||||
font-size: 7px;
|
||||
color: white;
|
||||
position: relative;
|
||||
top: -10px;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
.ajax-query-type{
|
||||
font-size: .8rem;
|
||||
/* form object row */
|
||||
.form-object-row{
|
||||
border: 1px lightgrey dashed;
|
||||
padding: 8px 12px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.form-object-row legend{
|
||||
font-weight: bold;
|
||||
color: grey;
|
||||
}
|
||||
|
||||
|
||||
.theme_viewer{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.theme{
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.theme1 h4{
|
||||
color: #cc8d17;
|
||||
border-bottom: 1px #cc8d17 solid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.theme2 h4{
|
||||
color: #c7306e;
|
||||
border-bottom: 1px #c7306e solid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
@@ -1,4 +1,9 @@
|
||||
|
||||
/**
|
||||
* Widgets Factory.
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
const iTopFormWidgetFactory = new function(){
|
||||
|
||||
/**
|
||||
@@ -6,42 +11,63 @@ const iTopFormWidgetFactory = new function(){
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
const AutoInstall = function()
|
||||
{
|
||||
const AutoInstall = function() {
|
||||
console.log('AutoInstall');
|
||||
|
||||
// SELECT widget implementation
|
||||
$('[data-widget="SelectWidget"]').each(function(e){
|
||||
const oElement = $(this);
|
||||
if(!oElement.data('widget-state-initialized')){
|
||||
const sId = oElement.attr('id');
|
||||
const aOptions = oElement.data('widget-options');
|
||||
iTopFormWidgetFactory.CreateSelectWidget(sId, aOptions);
|
||||
oElement.data('widget-state-initialized', true);
|
||||
}
|
||||
});
|
||||
// widgets catalog
|
||||
const WIDGETS = {
|
||||
SELECT: {name: 'SelectWidget', builder: CreateSelectWidget},
|
||||
TEXT: {name: 'TextWidget', builder: CreateTextWidget},
|
||||
AREA: {name: 'AreaWidget', builder: CreateAreaWidget}
|
||||
}
|
||||
|
||||
$('[data-widget="TextWidget"]').each(function(e){
|
||||
const oElement = $(this);
|
||||
if(!oElement.data('widget-state-initialized')){
|
||||
const sId = oElement.attr('id');
|
||||
const aOptions = oElement.data('widget-options');
|
||||
iTopFormWidgetFactory.CreateTextWidget(sId, aOptions);
|
||||
oElement.data('widget-state-initialized', true);
|
||||
}
|
||||
});
|
||||
// instanciate widgets...
|
||||
for (const widgetsKey in WIDGETS) {
|
||||
|
||||
// widget configuration
|
||||
const aWidgetConfiguration = WIDGETS[widgetsKey];
|
||||
|
||||
// instanciate widget
|
||||
$(`[data-widget="${aWidgetConfiguration.name}"]`).each(function (e) {
|
||||
const oElement = $(this);
|
||||
if (!oElement.data('widget-state-initialized')) {
|
||||
const sId = oElement.attr('id');
|
||||
const aOptions = oElement.data('widget-options');
|
||||
aWidgetConfiguration.builder(sId, aOptions);
|
||||
console.log(aWidgetConfiguration.name, sId, aOptions);
|
||||
oElement.data('widget-state-initialized', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$('[data-widget="AreaWidget"]').each(function(e){
|
||||
const oElement = $(this);
|
||||
if(!oElement.data('widget-state-initialized')){
|
||||
const sId = oElement.attr('id');
|
||||
const aOptions = oElement.data('widget-options');
|
||||
iTopFormWidgetFactory.CreateAreaWidget(sId, aOptions);
|
||||
oElement.data('widget-state-initialized', true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* CreateTextWidget.
|
||||
*
|
||||
* @param {string} sId
|
||||
* @param {array} aOptions
|
||||
* @constructor
|
||||
*/
|
||||
const CreateTextWidget = function(sId, aOptions){
|
||||
|
||||
if(aOptions['pattern'] !== undefined){
|
||||
|
||||
const oElement = $(`#${sId}`);
|
||||
const oMask = IMask(oElement[0],
|
||||
{
|
||||
mask: aOptions['pattern'],
|
||||
lazy: false,
|
||||
}
|
||||
);
|
||||
oMask.on('accept', () => {
|
||||
masked = oMask.masked;
|
||||
oElement.closest('div').toggleClass('complete', masked.isComplete)
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateAreaWidget.
|
||||
*
|
||||
@@ -51,9 +77,6 @@ const iTopFormWidgetFactory = new function(){
|
||||
*/
|
||||
const CreateAreaWidget = function(sId, aOptions){
|
||||
|
||||
console.log('CreateAreaWidget', sId, aOptions);
|
||||
|
||||
|
||||
editor = CKEDITOR.replace(sId, {
|
||||
language: 'fr',
|
||||
stylesSet: 'my_styles',
|
||||
@@ -72,34 +95,6 @@ const iTopFormWidgetFactory = new function(){
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateTextWidget.
|
||||
*
|
||||
* @param {string} sId
|
||||
* @param {array} aOptions
|
||||
* @constructor
|
||||
*/
|
||||
const CreateTextWidget = function(sId, aOptions){
|
||||
|
||||
console.log('CreateTextWidget', sId, aOptions);
|
||||
|
||||
if(aOptions['pattern'] !== undefined){
|
||||
|
||||
const oElement = $(`#${sId}`);
|
||||
const oMask = IMask(oElement[0],
|
||||
{
|
||||
mask: aOptions['pattern'],
|
||||
lazy: false,
|
||||
}
|
||||
);
|
||||
oMask.on('accept', () => {
|
||||
masked = oMask.masked;
|
||||
oElement.closest('div').toggleClass('complete', masked.isComplete)
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateSelectAjaxWidget.
|
||||
*
|
||||
@@ -107,10 +102,8 @@ const iTopFormWidgetFactory = new function(){
|
||||
* @param {array} aOptions
|
||||
* @constructor
|
||||
*/
|
||||
const CreateSelectWidget = function(sId, aOptions){
|
||||
|
||||
console.log('CreateSelectAjaxWidget', sId, aOptions);
|
||||
|
||||
const CreateSelectWidget = function(sId, aOptions)
|
||||
{
|
||||
const aPlugins = {};
|
||||
|
||||
if(aOptions['max_items'] != '1'){
|
||||
@@ -144,10 +137,7 @@ const iTopFormWidgetFactory = new function(){
|
||||
};
|
||||
|
||||
return {
|
||||
AutoInstall,
|
||||
CreateTextWidget,
|
||||
CreateAreaWidget,
|
||||
CreateSelectWidget,
|
||||
AutoInstall
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -399,16 +399,17 @@ return array(
|
||||
'Combodo\\iTop\\Core\\MetaModel\\HierarchicalKey' => $baseDir . '/sources/Core/MetaModel/HierarchicalKey.php',
|
||||
'Combodo\\iTop\\DesignDocument' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => $baseDir . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\FormSDK\\Controller\\TestController' => $baseDir . '/sources/FormSDK/Controller/TestController.php',
|
||||
'Combodo\\iTop\\FormSDK\\Dto\\ObjectSearchDto' => $baseDir . '/sources/FormSDK/Dto/ObjectSearchDto.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\Description\\FormFieldDescription' => $baseDir . '/sources/FormSDK/Field/Description/FormFieldDescription.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\Description\\FormFieldTypeEnumeration' => $baseDir . '/sources/FormSDK/Field/Description/FormFieldTypeEnumeration.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\FormHelper' => $baseDir . '/sources/FormSDK/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\SelectHelper' => $baseDir . '/sources/FormSDK/Helper/SelectDataProvider.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\TwigHelper' => $baseDir . '/sources/FormSDK/Helper/TwigHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAddon\\FormFactoryAddonInterface' => $baseDir . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryAdapterInterface.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAddon\\FormFactoryObjectAddon' => $baseDir . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Controller\\TestController' => $baseDir . '/sources/FormImplementation/Controller/TestController.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',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\TwigHelper' => $baseDir . '/sources/FormImplementation/Helper/TwigHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\FormFieldDescription' => $baseDir . '/sources/FormSDK/Field/FormFieldDescription.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\FormFieldTypeEnumeration' => $baseDir . '/sources/FormSDK/Field/FormFieldTypeEnumeration.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAdapter\\FormFactoryAdapterInterface' => $baseDir . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryAdapterInterface.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAdapter\\FormFactoryObjectAdapter' => $baseDir . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormFactory' => $baseDir . '/sources/FormSDK/Service/FormFactory.php',
|
||||
'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\\FormObjectType' => $baseDir . '/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php',
|
||||
|
||||
@@ -808,16 +808,17 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f
|
||||
'Combodo\\iTop\\Core\\MetaModel\\HierarchicalKey' => __DIR__ . '/../..' . '/sources/Core/MetaModel/HierarchicalKey.php',
|
||||
'Combodo\\iTop\\DesignDocument' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\DesignElement' => __DIR__ . '/../..' . '/core/designdocument.class.inc.php',
|
||||
'Combodo\\iTop\\FormSDK\\Controller\\TestController' => __DIR__ . '/../..' . '/sources/FormSDK/Controller/TestController.php',
|
||||
'Combodo\\iTop\\FormSDK\\Dto\\ObjectSearchDto' => __DIR__ . '/../..' . '/sources/FormSDK/Dto/ObjectSearchDto.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\Description\\FormFieldDescription' => __DIR__ . '/../..' . '/sources/FormSDK/Field/Description/FormFieldDescription.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\Description\\FormFieldTypeEnumeration' => __DIR__ . '/../..' . '/sources/FormSDK/Field/Description/FormFieldTypeEnumeration.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\FormHelper' => __DIR__ . '/../..' . '/sources/FormSDK/Helper/FormHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\SelectHelper' => __DIR__ . '/../..' . '/sources/FormSDK/Helper/SelectDataProvider.php',
|
||||
'Combodo\\iTop\\FormSDK\\Helper\\TwigHelper' => __DIR__ . '/../..' . '/sources/FormSDK/Helper/TwigHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAddon\\FormFactoryAddonInterface' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryAdapterInterface.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAddon\\FormFactoryObjectAddon' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php',
|
||||
'Combodo\\iTop\\FormImplementation\\Controller\\TestController' => __DIR__ . '/../..' . '/sources/FormImplementation/Controller/TestController.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',
|
||||
'Combodo\\iTop\\FormImplementation\\Helper\\TwigHelper' => __DIR__ . '/../..' . '/sources/FormImplementation/Helper/TwigHelper.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\FormFieldDescription' => __DIR__ . '/../..' . '/sources/FormSDK/Field/FormFieldDescription.php',
|
||||
'Combodo\\iTop\\FormSDK\\Field\\FormFieldTypeEnumeration' => __DIR__ . '/../..' . '/sources/FormSDK/Field/FormFieldTypeEnumeration.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAdapter\\FormFactoryAdapterInterface' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryAdapterInterface.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FactoryAdapter\\FormFactoryObjectAdapter' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FactoryAdapter/FormFactoryObjectAdapter.php',
|
||||
'Combodo\\iTop\\FormSDK\\Service\\FormFactory' => __DIR__ . '/../..' . '/sources/FormSDK/Service/FormFactory.php',
|
||||
'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\\FormObjectType' => __DIR__ . '/../..' . '/sources/FormSDK/Symfony/Type/Compound/FormObjectType.php',
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
'name' => 'combodo/itop',
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '47aeb0cbd303fc27c06bae27b6447b1bef4d8e35',
|
||||
'reference' => '20949605c30bc7a83d0b554f4af23b6cf802c292',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
@@ -22,7 +22,7 @@
|
||||
'combodo/itop' => array(
|
||||
'pretty_version' => 'dev-develop',
|
||||
'version' => 'dev-develop',
|
||||
'reference' => '47aeb0cbd303fc27c06bae27b6447b1bef4d8e35',
|
||||
'reference' => '20949605c30bc7a83d0b554f4af23b6cf802c292',
|
||||
'type' => 'project',
|
||||
'install_path' => __DIR__ . '/../../',
|
||||
'aliases' => array(),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Controller;
|
||||
namespace Combodo\iTop\FormImplementation\Controller;
|
||||
|
||||
use Combodo\iTop\Controller\AbstractAppController;
|
||||
use Combodo\iTop\FormSDK\Dto\ObjectSearchDto;
|
||||
use Combodo\iTop\FormSDK\Helper\FormHelper;
|
||||
use Combodo\iTop\FormSDK\Helper\SelectDataProvider;
|
||||
use Combodo\iTop\FormImplementation\Dto\ObjectSearchDto;
|
||||
use Combodo\iTop\FormImplementation\Helper\FormHelper;
|
||||
use Combodo\iTop\FormImplementation\Helper\SelectDataProvider;
|
||||
use Combodo\iTop\FormSDK\Service\FormManager;
|
||||
use Combodo\iTop\Service\Base\ObjectRepository;
|
||||
use DateTime;
|
||||
@@ -29,7 +29,7 @@ use utils;
|
||||
class TestController extends AbstractAppController
|
||||
{
|
||||
|
||||
#[Route('/formSDK/test_Form', name: 'formSDK_test_form')]
|
||||
#[Route('/formSDK/test_form', name: 'formSDK_test_form')]
|
||||
public function form(Request $oRequest, FormManager $oFormManager, RouterInterface $oRouter): Response
|
||||
{
|
||||
// create factory
|
||||
@@ -82,7 +82,7 @@ class TestController extends AbstractAppController
|
||||
$oForm2->handleRequest($oRequest);
|
||||
|
||||
return $this->render('formSDK/theme.html.twig', [
|
||||
'name1' => 'Portal',
|
||||
'name1' => 'Portail',
|
||||
'name2' => 'Console',
|
||||
'form1' => $oForm1->createView(),
|
||||
'form2' => $oForm2->createView(),
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Dto;
|
||||
namespace Combodo\iTop\FormImplementation\Dto;
|
||||
|
||||
use Symfony\Component\Validator\Constraints as Assert;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Helper;
|
||||
namespace Combodo\iTop\FormImplementation\Helper;
|
||||
|
||||
use Combodo\iTop\Controller\AbstractAppController;
|
||||
use Combodo\iTop\FormSDK\Service\FormManager;
|
||||
@@ -24,10 +24,10 @@ class FormHelper
|
||||
*/
|
||||
static public function CreateSampleFormFactory(FormManager $oFormManager, RouterInterface $oRouter)
|
||||
{
|
||||
// build the form
|
||||
// create a factory
|
||||
$oFormFactory = $oFormManager->CreateFactory();
|
||||
|
||||
// add 2 person forms...
|
||||
// add X person forms...
|
||||
for($i = 0 ; $i < 2 ; $i++){
|
||||
|
||||
// retrieve person
|
||||
@@ -61,6 +61,11 @@ class FormHelper
|
||||
'required' => false
|
||||
], new DateTime('1979/06/27'));
|
||||
|
||||
// ready
|
||||
$oFormFactory->AddSwitchField('notify', [
|
||||
'label' => 'Veuillez m\'avertir en cas de changement',
|
||||
], true);
|
||||
|
||||
// blog - date
|
||||
$oFormFactory->AddAreaField('blog', [
|
||||
'label' => 'Blog',
|
||||
@@ -81,7 +86,7 @@ class FormHelper
|
||||
|
||||
], [
|
||||
'url' => 'http://localhost' . $oRouter->generate('formSDK_ajax_select'),
|
||||
'ajax_query_parameter' => 'query',
|
||||
'query_parameter' => 'query',
|
||||
'value_field' => 'breed',
|
||||
'label_field' => 'breed',
|
||||
'search_field' => 'breed',
|
||||
@@ -95,21 +100,33 @@ class FormHelper
|
||||
'required' => false
|
||||
], 'Person', 'SELECT Person', [], '', 20);
|
||||
|
||||
// requests - select with OQL
|
||||
$oFormFactory->AddSelectOqlField('requests', [
|
||||
'label' => 'Tickets',
|
||||
'required' => false
|
||||
], 'UserRequest', 'SELECT UserRequest', [], '', 20);
|
||||
|
||||
// mode - select with static data
|
||||
$oFormFactory->AddSelectField('mode', [
|
||||
'label' => 'Mon mode',
|
||||
'choices' => SelectDataProvider::GetModes(),
|
||||
'expanded' => true,
|
||||
'multiple' => false
|
||||
], '');
|
||||
'multiple' => false,
|
||||
'label_attr' => [
|
||||
'class' => 'radio-inline'
|
||||
]
|
||||
], '1');
|
||||
|
||||
// options - select with static data
|
||||
$oFormFactory->AddSelectField('option', [
|
||||
'label' => 'Mes options',
|
||||
'choices' => SelectDataProvider::GetOptions(),
|
||||
'expanded' => true,
|
||||
'multiple' => true
|
||||
], null);
|
||||
'multiple' => true,
|
||||
'label_attr' => [
|
||||
'class' => 'checkbox-inline'
|
||||
]
|
||||
], ['0', '2','4']);
|
||||
|
||||
return $oFormFactory;
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Helper;
|
||||
namespace Combodo\iTop\FormImplementation\Helper;
|
||||
|
||||
use Dict;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Helper;
|
||||
namespace Combodo\iTop\FormImplementation\Helper;
|
||||
|
||||
use MetaModel;
|
||||
use Twig\Extension\AbstractExtension;
|
||||
@@ -17,7 +17,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Field\Description;
|
||||
namespace Combodo\iTop\FormSDK\Field;
|
||||
|
||||
/**
|
||||
* Description of a form field.
|
||||
@@ -31,12 +31,12 @@ class FormFieldDescription
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $sPath
|
||||
* @param string $sName
|
||||
* @param FormFieldTypeEnumeration $oType
|
||||
* @param array $aOptions
|
||||
*/
|
||||
public function __construct(
|
||||
private readonly string $sPath,
|
||||
private readonly string $sName,
|
||||
private readonly FormFieldTypeEnumeration $oType,
|
||||
private readonly array $aOptions
|
||||
)
|
||||
@@ -45,7 +45,7 @@ class FormFieldDescription
|
||||
}
|
||||
|
||||
/**
|
||||
* Get type.
|
||||
* Get field type.
|
||||
*
|
||||
* @return FormFieldTypeEnumeration
|
||||
*/
|
||||
@@ -55,7 +55,7 @@ class FormFieldDescription
|
||||
}
|
||||
|
||||
/**
|
||||
* Get options.
|
||||
* Get field options.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -65,10 +65,12 @@ class FormFieldDescription
|
||||
}
|
||||
|
||||
/**
|
||||
* Get field name.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function GetPath() : string
|
||||
public function GetName() : string
|
||||
{
|
||||
return $this->sPath;
|
||||
return $this->sName;
|
||||
}
|
||||
}
|
||||
@@ -17,10 +17,10 @@
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Field\Description;
|
||||
namespace Combodo\iTop\FormSDK\Field;
|
||||
|
||||
/**
|
||||
* Form types.
|
||||
* Types of fields.
|
||||
*
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
@@ -31,6 +31,7 @@ enum FormFieldTypeEnumeration : string
|
||||
case AREA = 'AREA';
|
||||
case DATE = 'DATE';
|
||||
case SELECT = 'SELECT';
|
||||
case SWITCH = 'SWITCH';
|
||||
case DB_OBJECT = 'DB_OBJECT';
|
||||
|
||||
/**
|
||||
@@ -40,10 +41,10 @@ enum FormFieldTypeEnumeration : string
|
||||
*/
|
||||
public function GetAvailableOptions() : array
|
||||
{
|
||||
$aOptions = ['label', 'required', 'disabled'];
|
||||
$aOptions = ['required', 'disabled', 'attr', 'label', 'label_attr'];
|
||||
|
||||
return match ($this->value) {
|
||||
FormFieldTypeEnumeration::SELECT => array_merge($aOptions, ['']),
|
||||
FormFieldTypeEnumeration::SELECT => array_merge($aOptions, ['placeholder']),
|
||||
default => $aOptions,
|
||||
};
|
||||
}
|
||||
@@ -37,7 +37,7 @@ interface FormFactoryAdapterInterface
|
||||
/**
|
||||
* Return description the form.
|
||||
*
|
||||
* @return \Combodo\iTop\FormSDK\Field\Description\FormFieldDescription[]
|
||||
* @return \Combodo\iTop\FormSDK\Field\FormFieldDescription[]
|
||||
*/
|
||||
public function GetFormDescriptions() : array;
|
||||
|
||||
|
||||
@@ -21,8 +21,8 @@ namespace Combodo\iTop\FormSDK\Service\FactoryAdapter;
|
||||
|
||||
use AttributeDefinition;
|
||||
use AttributeString;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use DBObject;
|
||||
use Exception;
|
||||
use ExceptionLog;
|
||||
@@ -89,8 +89,14 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
{
|
||||
$aOptions = [];
|
||||
|
||||
$sLabel = $oAttributeDefinition->GetLabel();
|
||||
if(!$this->bGroup){
|
||||
$sLabel = $this->GetLabel() . ' ••• ' . $sLabel;
|
||||
}
|
||||
|
||||
if($oAttributeDefinition instanceof AttributeString) {
|
||||
$aOptions['required'] = !$oAttributeDefinition->IsNullAllowed();
|
||||
$aOptions['label'] = $sLabel;
|
||||
}
|
||||
|
||||
return $aOptions;
|
||||
@@ -101,7 +107,7 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
*
|
||||
* @param string $sAttributeCode
|
||||
*
|
||||
* @return \Combodo\iTop\FormSDK\Field\Description\FormFieldDescription|null
|
||||
* @return \Combodo\iTop\FormSDK\Field\FormFieldDescription|null
|
||||
* @throws \Exception
|
||||
*/
|
||||
private function GetAttributeDescription(string $sAttributeCode) : ?FormFieldDescription
|
||||
@@ -110,7 +116,7 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
|
||||
if($oAttributeDefinition instanceof AttributeString) {
|
||||
return new FormFieldDescription(
|
||||
$this->GetAttributePath($sAttributeCode),
|
||||
$this->GetAttributeName($sAttributeCode),
|
||||
FormFieldTypeEnumeration::TEXT,
|
||||
array_merge(
|
||||
$this->GetAttributeOptions($oAttributeDefinition),
|
||||
@@ -122,16 +128,15 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Return attribute path.
|
||||
* Return attribute name.
|
||||
*
|
||||
* @param string $sAttributeCode
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function GetAttributePath(string $sAttributeCode) : string
|
||||
private function GetAttributeName(string $sAttributeCode) : string
|
||||
{
|
||||
return $this->bGroup ? $sAttributeCode : $this->GetIdentifier() . '-' . $sAttributeCode;
|
||||
// return $this->GetIdentifier() . '-' . $sAttributeCode;
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
@@ -140,10 +145,10 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
$aData = [];
|
||||
foreach ($this->aAttributes as $sAttributeCode => $oValue){
|
||||
try {
|
||||
$aData[$this->GetAttributePath($sAttributeCode)] = $this->GetAttributeData($sAttributeCode);
|
||||
$aData[$this->GetAttributeName($sAttributeCode)] = $this->GetAttributeData($sAttributeCode);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$aData[$this->GetAttributePath($sAttributeCode)] = null;
|
||||
$aData[$this->GetAttributeName($sAttributeCode)] = null;
|
||||
ExceptionLog::LogException($e);
|
||||
}
|
||||
}
|
||||
@@ -163,9 +168,9 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
{
|
||||
$aDescriptions = [];
|
||||
|
||||
foreach ($this->aAttributes as $sKey => $oValue){
|
||||
foreach ($this->aAttributes as $sAttCode => $oValue){
|
||||
try {
|
||||
$aDescriptions[$this->GetIdentifier() .'_' .$sKey] = $this->GetAttributeDescription($sKey);
|
||||
$aDescriptions[$this->GetAttributeName($sAttCode)] = $this->GetAttributeDescription($sAttCode);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
ExceptionLog::LogException($e);
|
||||
@@ -174,15 +179,21 @@ final class FormFactoryObjectAdapter implements FormFactoryAdapterInterface
|
||||
|
||||
if($this->bGroup){
|
||||
$oGroupDescriptions = new FormFieldDescription($this->GetIdentifier(), FormFieldTypeEnumeration::DB_OBJECT, [
|
||||
'descriptions' => $aDescriptions
|
||||
'descriptions' => $aDescriptions,
|
||||
'label' => $this->GetLabel()
|
||||
]);
|
||||
return [$oGroupDescriptions];
|
||||
return [$this->GetIdentifier() => $oGroupDescriptions];
|
||||
}
|
||||
else{
|
||||
return $aDescriptions;
|
||||
}
|
||||
}
|
||||
|
||||
public function GetLabel(): string
|
||||
{
|
||||
return get_class($this->oDBObject) . ' ' . $this->oDBObject->GetKey();
|
||||
}
|
||||
|
||||
/** @inheritdoc */
|
||||
public function GetIdentifier(): string
|
||||
{
|
||||
|
||||
@@ -20,11 +20,12 @@
|
||||
namespace Combodo\iTop\FormSDK\Service;
|
||||
|
||||
use Combodo\iTop\FormSDK\Helper\SelectDataProvider;
|
||||
use Combodo\iTop\FormSDK\Service\FormFactoryBuilderTrait;
|
||||
use Combodo\iTop\FormSDK\Service\FactoryAdapter\FormFactoryObjectAdapter;
|
||||
use Combodo\iTop\FormSDK\Service\FactoryAdapter\FormFactoryAdapterInterface;
|
||||
use Combodo\iTop\FormSDK\Symfony\SymfonyBridge;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use DBObject;
|
||||
use Symfony\Component\Form\ChoiceList\Loader\CallbackChoiceLoader;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
@@ -52,6 +53,9 @@ class FormFactory
|
||||
/** @var array $aData form data */
|
||||
private array $aData = [];
|
||||
|
||||
/** builder */
|
||||
use FormFactoryBuilderTrait;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
@@ -67,6 +71,8 @@ class FormFactory
|
||||
}
|
||||
|
||||
/**
|
||||
* Return descriptions and data arrays.
|
||||
*
|
||||
* @return array{descriptions:array, data:array}
|
||||
*/
|
||||
public function GetFormDescriptionsAndData() : array
|
||||
@@ -129,188 +135,12 @@ class FormFactory
|
||||
* Get form.
|
||||
*
|
||||
* @param string|null $sName
|
||||
*
|
||||
* @return \Symfony\Component\Form\FormInterface
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetForm(?string $sName): FormInterface
|
||||
public function GetForm(?string $sName = null) : mixed
|
||||
{
|
||||
['descriptions' => $aDescriptions, 'data' => $aData] = $this->GetFormDescriptionsAndData();
|
||||
return $this->oSymfonyBridge->GetForm($aDescriptions, $aData, $sName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add text field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddTextField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
// test widget for regex constraint
|
||||
if(array_key_exists('constraints', $aOptions)){
|
||||
$oConstraint = $aOptions['constraints'];
|
||||
if($oConstraint instanceof Regex){
|
||||
$aWidgetOptions = [
|
||||
'pattern' => $oConstraint->pattern,
|
||||
];
|
||||
$aOptions = array_merge([
|
||||
'attr' => [
|
||||
'data-widget' => 'TextWidget',
|
||||
'data-pattern' => $oConstraint->pattern,
|
||||
'data-widget-options' => json_encode($aWidgetOptions)
|
||||
]
|
||||
], $aOptions);
|
||||
}
|
||||
}
|
||||
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::TEXT, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add area field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddAreaField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$aOptions = array_merge([
|
||||
'attr' => [
|
||||
'data-widget' => 'AreaWidget',
|
||||
'data-widget-options' => json_encode([])
|
||||
]
|
||||
], $aOptions);
|
||||
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::AREA, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add date field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddDateField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::DATE, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSelectField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::SELECT, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dynamic ajax select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @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
|
||||
{
|
||||
// merge ajax options
|
||||
$aAjaxOptions = array_merge([
|
||||
'url' => '',
|
||||
'query_parameter' => 'query',
|
||||
'value_field' => 'value',
|
||||
'label_field' => 'label',
|
||||
'search_field' => 'search',
|
||||
'preload' => false,
|
||||
'threshold' => -1,
|
||||
'configuration' => 'AJAX'
|
||||
], $aAjaxOptions);
|
||||
|
||||
// merge options
|
||||
$aOptions = array_merge([
|
||||
'placeholder' => 'Select...',
|
||||
'attr' => [
|
||||
'data-widget' => 'SelectWidget',
|
||||
'data-ajax-query-type' => $aAjaxOptions['configuration'],
|
||||
'data-widget-options' => json_encode($aAjaxOptions)
|
||||
],
|
||||
// 'choice_loader' => new CallbackChoiceLoader(function() use ($aAjaxOptions, $aAjaxData): array {
|
||||
// $curl_data = utils::DoPostRequest($aAjaxOptions['url'], []);
|
||||
// $response_data = json_decode($curl_data);
|
||||
// if(count($response_data->items) > $aAjaxOptions['threshold']) return [];
|
||||
// $result = [];
|
||||
// foreach ($response_data->items as $e) {
|
||||
// $result[$e->breed] = $e->breed;
|
||||
// }
|
||||
// return $result;
|
||||
// }),
|
||||
], $aOptions);
|
||||
|
||||
return $this->AddSelectField($sKey, $aOptions, $oData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add dynamic OQL select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param string $sObjectClass
|
||||
* @param string $sOql
|
||||
* @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
|
||||
{
|
||||
$aAjaxData = [
|
||||
'class' => $sObjectClass,
|
||||
'oql' => $sOql,
|
||||
'fields' => '{'.implode($aFieldsToLoad).'}',
|
||||
];
|
||||
$sUrl = 'http://localhost' . $this->oRouter->generate('formSDK_object_search') . '?' . http_build_query($aAjaxData);
|
||||
$aAjaxOptions = [
|
||||
'url' => $sUrl,
|
||||
'query_parameter' => 'search',
|
||||
'value_field' => 'key',
|
||||
'label_field' => 'friendlyname',
|
||||
'search_field' => 'friendlyname',
|
||||
'threshold' => $iAjaxThershold,
|
||||
'configuration' => 'OQL'
|
||||
];
|
||||
return $this->AddSelectAjaxField($sKey, $aOptions, $aAjaxOptions, $aAjaxData, $oData);
|
||||
}
|
||||
}
|
||||
210
sources/FormSDK/Service/FormFactoryBuilderTrait.php
Normal file
210
sources/FormSDK/Service/FormFactoryBuilderTrait.php
Normal file
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Service;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Service\FormFactory;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Validator\Constraints\Regex;
|
||||
|
||||
trait FormFactoryBuilderTrait
|
||||
{
|
||||
|
||||
/**
|
||||
* Add text field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddTextField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
// test widget for regex constraint
|
||||
if(array_key_exists('constraints', $aOptions)){
|
||||
$oConstraint = $aOptions['constraints'];
|
||||
if($oConstraint instanceof Regex){
|
||||
$aWidgetOptions = [
|
||||
'pattern' => $oConstraint->pattern,
|
||||
];
|
||||
$aOptions = array_merge([
|
||||
'attr' => [
|
||||
'data-widget' => 'TextWidget',
|
||||
'data-pattern' => $oConstraint->pattern,
|
||||
'data-widget-options' => json_encode($aWidgetOptions)
|
||||
]
|
||||
], $aOptions);
|
||||
}
|
||||
}
|
||||
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::TEXT, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add area field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddAreaField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$aOptions = array_merge([
|
||||
'attr' => [
|
||||
'data-widget' => 'AreaWidget',
|
||||
'data-widget-options' => json_encode([])
|
||||
]
|
||||
], $aOptions);
|
||||
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::AREA, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add date field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddDateField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::DATE, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSelectField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::SELECT, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add dynamic ajax select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @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
|
||||
{
|
||||
// merge ajax options
|
||||
$aAjaxOptions = array_merge([
|
||||
'url' => '',
|
||||
'query_parameter' => 'query',
|
||||
'value_field' => 'value',
|
||||
'label_field' => 'label',
|
||||
'search_field' => 'search',
|
||||
'preload' => false,
|
||||
'threshold' => -1,
|
||||
'configuration' => 'AJAX'
|
||||
], $aAjaxOptions);
|
||||
|
||||
// merge options
|
||||
$aOptions = array_merge([
|
||||
'placeholder' => 'Select...',
|
||||
'attr' => [
|
||||
'data-widget' => 'SelectWidget',
|
||||
'data-ajax-query-type' => $aAjaxOptions['configuration'],
|
||||
'data-widget-options' => json_encode($aAjaxOptions)
|
||||
],
|
||||
// 'choice_loader' => new CallbackChoiceLoader(function() use ($aAjaxOptions, $aAjaxData): array {
|
||||
// $curl_data = utils::DoPostRequest($aAjaxOptions['url'], []);
|
||||
// $response_data = json_decode($curl_data);
|
||||
// if(count($response_data->items) > $aAjaxOptions['threshold']) return [];
|
||||
// $result = [];
|
||||
// foreach ($response_data->items as $e) {
|
||||
// $result[$e->breed] = $e->breed;
|
||||
// }
|
||||
// return $result;
|
||||
// }),
|
||||
], $aOptions);
|
||||
|
||||
return $this->AddSelectField($sKey, $aOptions, $oData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add dynamic OQL select field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param string $sObjectClass
|
||||
* @param string $sOql
|
||||
* @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
|
||||
{
|
||||
$aAjaxData = [
|
||||
'class' => $sObjectClass,
|
||||
'oql' => $sOql,
|
||||
'fields' => '{'.implode($aFieldsToLoad).'}',
|
||||
];
|
||||
$sUrl = 'http://localhost' . $this->oRouter->generate('formSDK_object_search') . '?' . http_build_query($aAjaxData);
|
||||
$aAjaxOptions = [
|
||||
'url' => $sUrl,
|
||||
'query_parameter' => 'search',
|
||||
'value_field' => 'key',
|
||||
'label_field' => 'friendlyname',
|
||||
'search_field' => 'friendlyname',
|
||||
'threshold' => $iAjaxThershold,
|
||||
'configuration' => 'OQL'
|
||||
];
|
||||
return $this->AddSelectAjaxField($sKey, $aOptions, $aAjaxOptions, $aAjaxData, $oData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add switch field.
|
||||
*
|
||||
* @param string $sKey
|
||||
* @param array $aOptions
|
||||
* @param mixed $oData
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function AddSwitchField(string $sKey, array $aOptions, mixed $oData = null) : FormFactory
|
||||
{
|
||||
$aOptions = array_merge([
|
||||
'label_attr' => ['class' => 'checkbox-switch'],
|
||||
], $aOptions);
|
||||
|
||||
$this->aDescriptions[$sKey] = new FormFieldDescription($sKey, FormFieldTypeEnumeration::SWITCH, $aOptions);
|
||||
$this->aData[$sKey] = $oData;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
* @package FormSDK
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class FormManager
|
||||
final class FormManager
|
||||
{
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,9 +20,10 @@
|
||||
namespace Combodo\iTop\FormSDK\Symfony;
|
||||
|
||||
use Combodo\iTop\FormSDK\Symfony\Type\Compound\FormObjectType;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldTypeEnumeration;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldTypeEnumeration;
|
||||
use LogAPI;
|
||||
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
@@ -54,7 +55,7 @@ class SymfonyBridge
|
||||
/**
|
||||
* Transform description to Symfony description.
|
||||
*
|
||||
* @param \Combodo\iTop\FormSDK\Field\Description\FormFieldDescription $oFormDescription
|
||||
* @param \Combodo\iTop\FormSDK\Field\FormFieldDescription $oFormDescription
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
@@ -64,32 +65,39 @@ class SymfonyBridge
|
||||
|
||||
case FormFieldTypeEnumeration::TEXT:
|
||||
return [
|
||||
'path' => $oFormDescription->GetPath(),
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => TextType::class,
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::AREA:
|
||||
return [
|
||||
'path' => $oFormDescription->GetPath(),
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => TextareaType::class,
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::DATE:
|
||||
return [
|
||||
'path' => $oFormDescription->GetPath(),
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => DateType::class,
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::SELECT:
|
||||
return [
|
||||
'path' => $oFormDescription->GetPath(),
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => ChoiceType::class,
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::SWITCH:
|
||||
return [
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => CheckboxType::class,
|
||||
'options' => $oFormDescription->GetOptions()
|
||||
];
|
||||
|
||||
case FormFieldTypeEnumeration::DB_OBJECT:
|
||||
$aOptions = $oFormDescription->GetOptions();
|
||||
$aItems = [];
|
||||
@@ -99,7 +107,7 @@ class SymfonyBridge
|
||||
}
|
||||
$aOptions['descriptions'] = $aItems;
|
||||
return [
|
||||
'path' => $oFormDescription->GetPath(),
|
||||
'name' => $oFormDescription->GetName(),
|
||||
'type' => FormObjectType::class,
|
||||
'options' => $aOptions
|
||||
];
|
||||
@@ -131,10 +139,12 @@ class SymfonyBridge
|
||||
// iterate throw descriptions...
|
||||
foreach ($aDescriptions as $oFormDescription){
|
||||
|
||||
// symfony form type description
|
||||
$aSymfony = $this->ToSymfonyFormType($oFormDescription);
|
||||
|
||||
// add type to form
|
||||
$oFormBuilder->add(
|
||||
$aSymfony['path'],
|
||||
$aSymfony['name'],
|
||||
$aSymfony['type'],
|
||||
$aSymfony['options']
|
||||
);
|
||||
@@ -147,7 +157,7 @@ class SymfonyBridge
|
||||
* @see https://itecnote.com/tecnote/php-disable-backend-validation-for-choice-field-in-symfony-2-type/
|
||||
*/
|
||||
if($aSymfony['type'] === ChoiceType::class){
|
||||
$oFormBuilder->get($aSymfony['path'])->resetViewTransformers();
|
||||
$oFormBuilder->get($aSymfony['name'])->resetViewTransformers();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace Combodo\iTop\FormSDK\Symfony\Type\Compound;
|
||||
|
||||
use Combodo\iTop\FormSDK\Field\Description\FormFieldDescription;
|
||||
use Combodo\iTop\FormSDK\Field\FormFieldDescription;
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
@@ -39,7 +39,7 @@ class FormObjectType extends AbstractType
|
||||
{
|
||||
/** @var FormFieldDescription $oDescription */
|
||||
foreach ($options['descriptions'] as $oDescription){
|
||||
$builder->add($oDescription['path'], $oDescription['type'], $oDescription['options']);
|
||||
$builder->add($oDescription['name'], $oDescription['type'], $oDescription['options']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
controllers:
|
||||
resource:
|
||||
path: ../../sources/FormSDK/Controller/
|
||||
namespace: Combodo\iTop\FormSDK\Controller
|
||||
path: ../../sources/FormImplementation/Controller/
|
||||
namespace: Combodo\iTop\FormImplementation\Controller
|
||||
type: attribute
|
||||
|
||||
@@ -17,7 +17,7 @@ services:
|
||||
resource: '../../sources'
|
||||
exclude:
|
||||
- '../../sources/alias.php'
|
||||
- '../../sources/FormSDK/Symfony/Type'
|
||||
- '../../sources/FormImplementation/Symfony/Type'
|
||||
- '../../sources/Application/WebPage'
|
||||
|
||||
# add more service definitions when explicit configuration is needed
|
||||
|
||||
@@ -3,7 +3,9 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="container">
|
||||
<div class="container p-5">
|
||||
|
||||
<h3>Form SDK : Components</h3>
|
||||
|
||||
{# specific form theme #}
|
||||
{% if theme is defined %}
|
||||
|
||||
@@ -1,9 +1,35 @@
|
||||
|
||||
{% extends 'base.html.twig' %}
|
||||
|
||||
{% block stylesheets %}
|
||||
|
||||
<style>
|
||||
.theme_viewer{
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.theme{
|
||||
width: 100%;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.theme1 h4{
|
||||
color: #cc8d17;
|
||||
border-bottom: 1px #cc8d17 solid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.theme2 h4{
|
||||
color: #c7306e;
|
||||
border-bottom: 1px #c7306e solid;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
</style>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="container-fluid p-5">
|
||||
|
||||
{# specific form theme #}
|
||||
{% if theme1 is defined %}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
{%- endblock form_label -%}
|
||||
|
||||
{%- block form_object_row -%}
|
||||
{%- set row_attr = row_attr|merge({class: 'mb-3 form-object'}) -%}
|
||||
{%- set row_attr = row_attr|merge({class: 'mb-3 form-object-row'}) -%}
|
||||
{{ form_row(form, {'row_attr': row_attr}) }}
|
||||
{%- endblock form_object_row -%}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user