Feature: #79440 - FormEngine Element Expansion
See forge#79440
Description
A new API in FormEngine has been introduced that allows fine grained additions to single elements and containers without substituting the whole element.
For elements within the TCA
config section, three new options have been introduced:
field
An array of single field information. This could be additionally describing text that is rendered between the element label and the element itself. Field information are restricted, only a couple of HTML tags are allowed within the result HTML.Information field
An array of single field controls. These are icons with JavaScript or links to further functionality of the framework. They are usually displayed next to the element. Each control must return an icon identifier, a title, and an array of a-tag attributes.Control field
Additional functionality enriching the element. These are typically shown below the element. Wizards may return any HTML.Wizard
For FormEngine containers, the same API has been introduced, but it is currently only implemented within
the Outer
which renders the record title and delegates the main record rendering to
a different container. Adding field
or field
here allows embedding additional
functionality between the record title an the main record body.
Single elements and containers may register default information, control and wizards. The configuration is merged
with any possibly given configuration from TCA
.
Example from Group
:
class GroupElement extends AbstractFormElement
{
/**
* Default field controls for this element.
*
* @var array
*/
protected $defaultFieldControl = [
'elementBrowser' => [
'renderType' => 'elementBrowser',
],
'insertClipboard' => [
'renderType' => 'insertClipboard',
'after' => [ 'elementBrowser' ],
],
'editPopup' => [
'renderType' => 'editPopup',
'disabled' => true,
'after' => [ 'insertClipboard' ],
],
'addRecord' => [
'renderType' => 'addRecord',
'disabled' => true,
'after' => [ 'editPopup' ],
],
'listModule' => [
'renderType' => 'listModule',
'disabled' => true,
'after' => [ 'addRecord' ],
],
];
public function render()
{
...
$fieldControlResult = $this->renderFieldControl();
$fieldControlHtml = $legacyFieldControlHtml . $fieldControlResult['html'];
$resultArray = $this->mergeChildReturnIntoExistingResult($resultArray, $fieldControlResult, false);
}
}
This element registers five default field controls (icons next to the element), renders them and later
adds the HTML at an appropriate place within the HTML of the main element. The default
can
be overwritten on TCA
level of single fields:
'columns' => [
'aField' => [
'label' => 'aField',
'config' => [
'fieldControl' => [
'elementBrowser' => [
'disabled' => true,
],
'editPopup' => [
'disabled' => false,
],
'aNewControl' => [
'renderType' => 'myOwnTypeGroupControl',
'before' => [ 'elementBrowser' ],
],
],
],
],
],
The above configuration disables the element browser which is enabled by default, it enabled the edit popup
control which exists in default configuration but is disabled by default, and it adds a further control called
a
with render
. The renderType instructs the FormEngine
Node
to instantiate the class that in configured for that renderType, identical to other usages
of the NodeFactory, this lookup can be manipulated on configuration and code level. In the example above, a new
renderType should be registered in ext_
:
$GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['nodeRegistry'][1485351217] = [
'nodeName' => 'myOwnTypeGroupControl',
'priority' => 30,
'class' => \My\ExtensionName\Form\FieldControl\MyFancyControl::class,
];
Note the above configuration also uses the Dependency
: It is possible to resort single
elements by adding before
and after
to the configuration. In above example, the new
control a
would be shown as first control, before element
.
The first level below field
contains speaking names of single controls, each control must
have a render
defined (either on TCA level or via defaultFieldControl), and they may have
a before
and after
and a disabled
setting. Each control also may have a options
sub array with further settings given to the specific control.
In TCA
, the configuration name for field controls is field
, for wizards it is field
,
and for information it is field
. All three follow the same structure. It is up to a single element
if all three of these are actually called and rendered. For instance, it sometimes does not make sense to have
field controls in all elements, so some elements skip that.
For containers, the configuration of field
, field
and field
is within
the ctrl
section of TCA
. This is currently only implemented within the Outer
for
field
and field
.
Example:
'ctrl' => [
...
'container' => [
'outerWrapContainer' => [
'fieldInformation' => [
'myHelloWorld' => [
'renderType' => 'helloWorld',
],
],
],
],
],
The above example would instruct the system to call the class registered for renderType hello
within the OuterWrapContainer.
Impact
The new API brings lots of new options to add functionality to single elements without substituting the full element.