From 88fe986f64fcb3a30c23b9806c772350bc12d8b1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Jacob?= <bjoern.jacob@tritum.de>
Date: Fri, 25 Feb 2022 11:54:52 +0100
Subject: [PATCH] [DOCS] Restructure API Reference

The API Reference of the form framework resided inside the docs for
integrators. This patch creates a new main chapter "For Developers/
API Reference" and moves all the related content there. In addition,
the content has been splitted in three documents.

Resolves: #97039
Releases: main, 11.5
Change-Id: Ie626f3ebdd137dfb7aef308b1bf7568dc17de985
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73710
Tested-by: Colin Findeisen <colin.findeisen@tritum.de>
Tested-by: core-ci <typo3@b13.com>
Tested-by: waldhacker <hello@waldhacker.dev>
Reviewed-by: Colin Findeisen <colin.findeisen@tritum.de>
Reviewed-by: waldhacker <hello@waldhacker.dev>
---
 .../Documentation/D/FinisherOptions/Index.rst | 1165 ++++
 .../form/Documentation/D/FormEditor/Index.rst | 2691 ++++++++
 .../AbstractRenderable/getRootForm.rst        |    0
 .../AbstractRenderable/setIdentifier.rst      |    0
 .../AbstractRenderable/setLabel.rst           |    0
 .../AbstractRenderable/setOptions.rst         |    0
 .../AbstractSection/addElement.rst            |    0
 .../AbstractSection/getElements.rst           |    0
 .../getElementsRecursively.rst                |    0
 .../AbstractSection/moveElementAfter.rst      |    0
 .../AbstractSection/moveElementBefore.rst     |    0
 .../AbstractSection/removeElement.rst         |    0
 .../FormElementInterface/addValidator.rst     |    0
 .../FormElementInterface/createValidator.rst  |    0
 .../FormElementInterface/getDefaultValue.rst  |    0
 .../FormElementInterface/getProperties.rst    |    0
 .../getUniqueIdentifier.rst                   |    0
 .../initializeFormElement.rst                 |    0
 .../FormElementInterface/isRequired.rst       |    0
 .../FormElementInterface/setDataType.rst      |    0
 .../FormElementInterface/setDefaultValue.rst  |    0
 .../FormElementInterface/setProperty.rst      |    0
 .../setRenderingOption.rst                    |    0
 .../D/FrontendRendering/Index.rst             | 1668 +++++
 .../getParentRenderable.rst                   |    0
 .../RenderableInterface/getTemplateName.rst   |    0
 .../setParentRenderable.rst                   |    0
 .../RootRenderableInterface/getIdentifier.rst |    0
 .../RootRenderableInterface/getLabel.rst      |    0
 .../getRendererClassName.rst                  |    0
 .../getRenderingOptions.rst                   |    0
 .../RootRenderableInterface/getType.rst       |    0
 typo3/sysext/form/Documentation/D/Index.rst   |   18 +
 .../Documentation/I/ApiReference/Index.rst    | 5533 -----------------
 typo3/sysext/form/Documentation/I/Index.rst   |    1 -
 typo3/sysext/form/Documentation/Index.rst     |    1 +
 36 files changed, 5543 insertions(+), 5534 deletions(-)
 create mode 100644 typo3/sysext/form/Documentation/D/FinisherOptions/Index.rst
 create mode 100644 typo3/sysext/form/Documentation/D/FormEditor/Index.rst
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractRenderable/getRootForm.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractRenderable/setIdentifier.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractRenderable/setLabel.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractRenderable/setOptions.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/addElement.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/getElements.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/getElementsRecursively.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/moveElementAfter.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/moveElementBefore.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/AbstractSection/removeElement.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/addValidator.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/createValidator.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/getDefaultValue.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/getProperties.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/getUniqueIdentifier.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/initializeFormElement.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/isRequired.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/setDataType.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/setDefaultValue.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/setProperty.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/FormElementInterface/setRenderingOption.rst (100%)
 create mode 100644 typo3/sysext/form/Documentation/D/FrontendRendering/Index.rst
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RenderableInterface/getParentRenderable.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RenderableInterface/getTemplateName.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RenderableInterface/setParentRenderable.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RootRenderableInterface/getIdentifier.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RootRenderableInterface/getLabel.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RootRenderableInterface/getRendererClassName.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RootRenderableInterface/getRenderingOptions.rst (100%)
 rename typo3/sysext/form/Documentation/{I/ApiReference => D/FrontendRendering}/RootRenderableInterface/getType.rst (100%)
 create mode 100644 typo3/sysext/form/Documentation/D/Index.rst
 delete mode 100644 typo3/sysext/form/Documentation/I/ApiReference/Index.rst

diff --git a/typo3/sysext/form/Documentation/D/FinisherOptions/Index.rst b/typo3/sysext/form/Documentation/D/FinisherOptions/Index.rst
new file mode 100644
index 000000000000..6d2f89a0313a
--- /dev/null
+++ b/typo3/sysext/form/Documentation/D/FinisherOptions/Index.rst
@@ -0,0 +1,1165 @@
+.. include:: /Includes.rst.txt
+
+
+.. _apireference-finisheroptions:
+
+Finisher Options
+================
+
+.. _apireference-finisheroptions-closurefinisher:
+
+Closure finisher
+----------------
+
+This finisher can only be used in programmatically-created forms. It makes it
+possible to execute one's own finisher code without having to implement/
+declare this finisher.
+
+Usage through code::
+
+   $closureFinisher = GeneralUtility::makeInstance(ClosureFinisher::class);
+   $closureFinisher->setOption('closure', function($finisherContext) {
+       $formRuntime = $finisherContext->getFormRuntime();
+       // ...
+   });
+   $formDefinition->addFinisher($closureFinisher);
+
+
+.. _apireference-finisheroptions-closurefinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-closurefinisher-options-closure:
+
+closure
++++++++
+
+:aspect:`Data type`
+      \Closure
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      null
+
+
+.. _apireference-finisheroptions-confirmationfinisher:
+
+Confirmation finisher
+---------------------
+
+A simple finisher that outputs a given text.
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: Confirmation
+       options:
+         message: 'Thx for using TYPO3'
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('Confirmation', [
+       'message' => 'foo',
+   ]);
+
+or create manually (not preferred)::
+
+   $confirmationFinisher = GeneralUtility::makeInstance(ConfirmationFinisher::class);
+   $confirmationFinisher->setOptions([
+       'message' => 'foo',
+   ]);
+   $formDefinition->addFinisher($confirmationFinisher);
+
+
+.. _apireference-finisheroptions-confirmationfinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-confirmationfinisher-options-message:
+
+message
++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      The form has been submitted.
+
+
+.. _apireference-finisheroptions-deleteuploadsfinisher:
+
+DeleteUploads finisher
+----------------------
+
+This finisher remove the currently submited files.
+Use this finisher e.g after the email finisher if you don't want to keep the files online.
+
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: DeleteUploads
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('DeleteUploads');
+
+or create manually (not preferred)::
+
+   $deleteUploadsFinisher = GeneralUtility::makeInstance(DeleteUploadsFinisher::class);
+   $formDefinition->addFinisher($deleteUploadsFinisher);
+
+
+.. _apireference-finisheroptions-emailfinisher:
+
+Email finisher
+--------------
+
+This finisher sends an email to one recipient.
+EXT:form uses 2 EmailFinisher declarations with the identifiers ``EmailToReceiver`` and ``EmailToSender``.
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: EmailToReceiver
+       options:
+         subject: 'Your message'
+         recipientAddress: your.company@example.com
+         recipientName: 'Your Company name'
+         senderAddress: 'form@example.com'
+         senderName: 'form submitter'
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('EmailToReceiver', [
+       'subject' => 'Your message',
+       'recipientAddress' => 'your.company@example.com',
+       'recipientName' => 'Your Company name',
+       'senderAddress' => 'form@example.com',
+       'senderName' => 'form submitter',
+   ]);
+
+or create manually (not preferred)::
+
+   $emailFinisher = GeneralUtility::makeInstance(EmailFinisher::class);
+   $emailFinisher->setOptions([
+       'subject' => 'Your message',
+       'recipientAddress' => 'your.company@example.com',
+       'recipientName' => 'Your Company name',
+       'senderAddress' => 'form@example.com',
+       'senderName' => 'form submitter',
+   ]);
+   $formDefinition->addFinisher($emailFinisher);
+
+
+.. _apireference-finisheroptions-emailfinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-emailfinisher-options-subject:
+
+subject
++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Subject of the email
+
+
+.. _apireference-finisheroptions-emailfinisher-options-recipientaddress:
+
+recipientAddress
+++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Email address of the recipient (To)
+
+
+.. _apireference-finisheroptions-emailfinisher-options-recipientname:
+
+recipientName
++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty string
+
+:aspect:`Description`
+      Human-readable name of the recipient
+
+
+.. _apireference-finisheroptions-emailfinisher-options-senderaddress:
+
+senderAddress
++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Email address of the sender/ visitor (From)
+
+
+.. _apireference-finisheroptions-emailfinisher-options-sendername:
+
+senderName
+++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty string
+
+:aspect:`Description`
+      Human-readable name of the sender
+
+
+.. _apireference-finisheroptions-emailfinisher-options-replytoaddress:
+
+replyToAddress
+++++++++++++++
+
+:aspect:`Data type`
+      string/ array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Email address of to be used as reply-to email (use multiple addresses with an array)
+
+.. note::
+
+   For the moment, the ``form editor`` cannot deal with multiple reply-to addresses (use multiple addresses with an array)
+
+
+.. _apireference-finisheroptions-emailfinisher-options-carboncopyaddress:
+
+carbonCopyAddress
++++++++++++++++++
+
+:aspect:`Data type`
+      string/ array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Email address of the copy recipient (use multiple addresses with an array)
+
+.. note::
+
+   For the moment, the ``form editor`` cannot deal with multiple copy recipient addresses (use multiple addresses with an array)
+
+
+.. _apireference-finisheroptions-emailfinisher-options-blindcarboncopyaddress:
+
+blindCarbonCopyAddress
+++++++++++++++++++++++
+
+:aspect:`Data type`
+      string/ array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Email address of the blind copy recipient (use multiple addresses with an array)
+
+.. note::
+
+   For the moment, the ``form editor`` cannot deal with multiple blind copy recipient addresses (use multiple addresses with an array)
+
+
+.. _apireference-finisheroptions-emailfinisher-options-format:
+
+format
+++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      html
+
+:aspect:`possible values`
+      html/ plaintext
+
+:aspect:`Description`
+      The format of the email. By default mails are sent as HTML.
+
+
+.. _apireference-finisheroptions-emailfinisher-options-attachuploads:
+
+attachUploads
++++++++++++++
+
+:aspect:`Data type`
+      bool
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      true
+
+:aspect:`Description`
+      If set, all uploaded items are attached to the email.
+
+
+.. _apireference-finisheroptions-emailfinisher-options-translation-translationfiles:
+
+translation.translationFiles
+++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      string/ array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      If set, this translation file(s) will be used for finisher option translations.
+      If not set, the translation file(s) from the 'Form' element will be used.
+      Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
+
+
+.. _apireference-finisheroptions-emailfinisher-options-translation-language:
+
+translation.language
+++++++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      If not set, the finisher options are translated depending on the current frontend language (if translations exists).
+      This option allows you to force translations for a given language isocode, e.g 'dk' or 'de'.
+      Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
+
+
+.. _apireference-finisheroptions-emailfinisher-options-layoutrootpaths:
+
+layoutRootPaths
++++++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Fluid layout paths
+
+
+.. _apireference-finisheroptions-emailfinisher-options-partialrootpaths:
+
+partialRootPaths
+++++++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Fluid partial paths
+
+
+.. _apireference-finisheroptions-emailfinisher-options-templaterootpaths:
+
+templateRootPaths
++++++++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      Fluid template paths; all templates get the current :php:`FormRuntime`
+      assigned as :code:`form` and the :php:`FinisherVariableProvider` assigned
+      as :code:`finisherVariableProvider`.
+
+
+.. _apireference-finisheroptions-emailfinisher-options-variables:
+
+variables
++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
+      undefined
+
+:aspect:`Description`
+      associative array of variables which are available inside the Fluid template
+
+
+.. _apireference-finisheroptions-flashmessagefinisher:
+
+FlashMessage finisher
+---------------------
+
+A simple finisher that adds a message to the FlashMessageContainer.
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: FlashMessage
+       options:
+         messageTitle: 'Merci'
+         messageCode: 201905041245
+         messageBody: 'Thx for using %s'
+         messageArguments:
+           - 'TYPO3'
+         severity: 0
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('FlashMessage', [
+       'messageTitle' => 'Merci',
+       'messageCode' => 201905041245,
+       'messageBody' => 'Thx for using %s',
+       'messageArguments' => ['TYPO3'],
+       'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
+   ]);
+
+or create manually (not preferred)::
+
+   $flashMessageFinisher = GeneralUtility::makeInstance(FlashMessageFinisher::class);
+   $flashMessageFinisher->setOptions([
+       'messageTitle' => 'Merci',
+       'messageCode' => 201905041245,
+       'messageBody' => 'Thx for using %s',
+       'messageArguments' => ['TYPO3'],
+       'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
+   ]);
+   $formDefinition->addFinisher($flashMessageFinisher);
+
+
+.. _apireference-finisheroptions-flashmessagefinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-flashmessagefinisher-options-messagebody:
+
+messageBody
++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Description`
+      The flash message body
+
+
+.. _apireference-finisheroptions-flashmessagefinisher-options-messagetitle:
+
+messageTitle
+++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty string
+
+:aspect:`Description`
+      The flash message title, if needed
+
+
+.. _apireference-finisheroptions-flashmessagefinisher-options-messagearguments:
+
+messageArguments
+++++++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty array
+
+:aspect:`Description`
+      The flash message arguments, if needed
+
+
+.. _apireference-finisheroptions-flashmessagefinisher-options-messagecode:
+
+messageCode
++++++++++++
+
+:aspect:`Data type`
+      int
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Description`
+      The flash message code
+
+
+.. _apireference-finisheroptions-flashmessagefinisher-options-severity:
+
+severity
+++++++++
+
+:aspect:`Data type`
+      int
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      \TYPO3\CMS\Core\Messaging\AbstractMessage::OK (0)
+
+:aspect:`Description`
+      The flash message severity code.
+      See \TYPO3\CMS\Core\Messaging\AbstractMessage constants for the codes.
+
+
+.. _apireference-finisheroptions-redirectfinisher:
+
+Redirect finisher
+-----------------
+
+A simple finisher that redirects to another page.
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: Redirect
+       options:
+         pageUid: 1
+         additionalParameters: 'param1=value1&param2=value2'
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('Redirect', [
+       'pageUid' => 1,
+       'additionalParameters' => 'param1=value1&param2=value2',
+   ]);
+
+or create manually (not preferred)::
+
+   $redirectFinisher = GeneralUtility::makeInstance(RedirectFinisher::class);
+   $redirectFinisher->setOptions([
+       'pageUid' => 1,
+       'additionalParameters' => 'param1=value1&param2=value2',
+   ]);
+   $formDefinition->addFinisher($redirectFinisher);
+
+
+.. _apireference-finisheroptions-redirectfinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-redirectfinisher-options-pageuid:
+
+pageUid
++++++++
+
+:aspect:`Data type`
+      int
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      1
+
+:aspect:`Description`
+      Redirect to this page uid
+
+
+.. _apireference-finisheroptions-redirectfinisher-options-additionalparameters:
+
+additionalParameters
+++++++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty string
+
+:aspect:`Description`
+      Additional parameters which should be used on the target page
+
+
+.. _apireference-finisheroptions-redirectfinisher-options-delay:
+
+delay
++++++
+
+:aspect:`Data type`
+      int
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      0
+
+:aspect:`Description`
+      The redirect delay in seconds.
+
+
+.. _apireference-finisheroptions-redirectfinisher-options-statuscode:
+
+statusCode
+++++++++++
+
+:aspect:`Data type`
+      int
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      303
+
+:aspect:`Description`
+      The HTTP status code for the redirect. Default is "303 See Other".
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher:
+
+SaveToDatabase finisher
+-----------------------
+
+This finisher saves the data from a submitted form into a database table.
+
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: SaveToDatabase
+       options:
+         table: 'fe_users'
+         mode: update
+         whereClause:
+           uid: 1
+         databaseColumnMappings:
+           tstamp:
+             value: '{__currentTimestamp}'
+           pid:
+             value: 1
+         elements:
+           textfield-identifier-1:
+             mapOnDatabaseColumn: 'first_name'
+           textfield-identifier-2:
+             mapOnDatabaseColumn: 'last_name'
+           textfield-identifier-3:
+             mapOnDatabaseColumn: 'username'
+           advancedpassword-1:
+             mapOnDatabaseColumn: 'password'
+             skipIfValueIsEmpty: true
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('SaveToDatabase', [
+       'table' => 'fe_users',
+       'mode' => 'update',
+       'whereClause' => [
+           'uid' => 1,
+       ],
+       'databaseColumnMappings' => [
+           'pid' => ['value' => 1],
+       ],
+       'elements' => [
+           'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
+           'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
+           'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
+           'advancedpassword-1' => [
+               'mapOnDatabaseColumn' => 'password',
+               'skipIfValueIsEmpty' => true,
+           ],
+       ],
+   ]);
+
+or create manually (not preferred)::
+
+   $saveToDatabaseFinisher = GeneralUtility::makeInstance(SaveToDatabaseFinisher::class);
+   $saveToDatabaseFinisher->setOptions([
+       'table' => 'fe_users',
+       'mode' => 'update',
+       'whereClause' => [
+           'uid' => 1,
+       ],
+       'databaseColumnMappings' => [
+           'pid' => ['value' => 1],
+       ],
+       'elements' => [
+           'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
+           'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
+           'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
+           'advancedpassword-1' => [
+               'mapOnDatabaseColumn' => 'password',
+               'skipIfValueIsEmpty' => true,
+           ],
+       ],
+   ]);
+   $formDefinition->addFinisher($saveToDatabaseFinisher);
+
+You can write options as an array to perform multiple database operations.
+
+Usage within form definition
+
+.. code-block:: yaml
+
+   identifier: example-form
+   label: 'example'
+   type: Form
+
+   finishers:
+     -
+       identifier: SaveToDatabase
+       options:
+         1:
+           table: 'my_table'
+           mode: insert
+           databaseColumnMappings:
+             some_column:
+               value: 'cool'
+         2:
+           table: 'my_other_table'
+           mode: update
+           whereClause:
+             pid: 1
+           databaseColumnMappings:
+             some_other_column:
+               value: '{SaveToDatabase.insertedUids.1}'
+   ...
+
+
+Usage through code::
+
+   $formDefinition->createFinisher('SaveToDatabase', [
+       1 => [
+           'table' => 'my_table',
+           'mode' => 'insert',
+           'databaseColumnMappings' => [
+               'some_column' => ['value' => 'cool'],
+           ],
+       ],
+       2 => [
+           'table' => 'my_other_table',
+           'mode' => 'update',
+           'whereClause' => [
+               'pid' => 1,
+           ],
+           'databaseColumnMappings' => [
+               'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
+           ],
+       ],
+   ]);
+
+or create manually (not preferred)::
+
+   $saveToDatabaseFinisher = GeneralUtility::makeInstance(SaveToDatabaseFinisher::class);
+   $saveToDatabaseFinisher->setOptions([
+       1 => [
+           'table' => 'my_table',
+           'mode' => 'insert',
+           'databaseColumnMappings' => [
+               'some_column' => ['value' => 'cool'],
+           ],
+       ],
+       2 => [
+           'table' => 'my_other_table',
+           'mode' => 'update',
+           'whereClause' => [
+               'pid' => 1,
+           ],
+           'databaseColumnMappings' => [
+               'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
+           ],
+       ],
+   ]);
+   $formDefinition->addFinisher($saveToDatabaseFinisher);
+
+
+This performs 2 database operations.
+One insert and one update.
+You can access the inserted uids through '{SaveToDatabase.insertedUids.<theArrayKeyNumberWithinOptions>}'
+If you perform a insert operation, the value of the inserted database row will be stored within the FinisherVariableProvider.
+<theArrayKeyNumberWithinOptions> references to the numeric options.* key.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options:
+
+Options
+^^^^^^^
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-table:
+
+table
++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      null
+
+:aspect:`Description`
+      Insert or update values into this table.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-mode:
+
+mode
+++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      'insert'
+
+:aspect:`Possible values`
+      insert/ update
+
+:aspect:`Description`
+      ``insert`` will create a new database row with the values from the submitted form and/or some predefined values. @see options.elements and options.databaseFieldMappings
+
+      ``update`` will update a given database row with the values from the submitted form and/or some predefined values. 'options.whereClause' is then required.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-whereclause:
+
+whereClause
++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      Yes, if mode = update
+
+:aspect:`Default value`
+      empty array
+
+:aspect:`Description`
+      This where clause will be used for a database update action
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-elements:
+
+elements
+++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      empty array
+
+:aspect:`Description`
+      Use ``options.elements`` to map form element values to existing database columns.
+      Each key within ``options.elements`` has to match with a form element identifier.
+      The value for each key within ``options.elements`` is an array with additional informations.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-mapondatabasecolumn:
+
+elements.<formElementIdentifier>.mapOnDatabaseColumn
+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      undefined
+
+:aspect:`Description`
+      The value from the submitted form element with the identifier ``<formElementIdentifier>`` will be written into this database column.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-skipifvalueisempty:
+
+elements.<formElementIdentifier>.skipIfValueIsEmpty
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      bool
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      false
+
+:aspect:`Description`
+      Set this to true if the database column should not be written if the value from the submitted form element with the identifier
+      ``<formElementIdentifier>`` is empty (think about password fields etc.). Empty means strings without content, whitespace is valid content.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-savefileidentifierinsteadofuid:
+
+elements.<formElementIdentifier>.saveFileIdentifierInsteadOfUid
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      bool
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      false
+
+:aspect:`Description`
+      Set this to true if the database column should not be written if the value from the submitted form element with the identifier
+      ``<formElementIdentifier>`` is empty (think about password fields etc.).
+
+      This setting only rules for form elements which creates a FAL object like ``FileUpload`` or ``ImageUpload``.
+      By default, the uid of the FAL object will be written into the database column. Set this to true if you want to store the
+      FAL identifier (1:/user_uploads/some_uploaded_pic.jpg) instead.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-dateformat:
+
+elements.<formElementIdentifier>.dateFormat
++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      'U'
+
+:aspect:`Description`
+      If the internal datatype is :php:`\DateTime` which is true for the form element types
+      :yaml:`DatePicker` and :yaml:`Date`, the object needs to be converted into a string value.
+      This option allows you to define the format of the date in case of such a conversion.
+      You can use every format accepted by the PHP :php:`date()` function (https://php.net/manual/en/function.date.php#refsect1-function.date-parameters).
+      The default value is "U" which leads to a Unix timestamp.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings:
+
+databaseColumnMappings
+++++++++++++++++++++++
+
+:aspect:`Data type`
+      array
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      empty array
+
+:aspect:`Description`
+      Use this to map database columns to static values.
+      Each key within ``options.databaseColumnMappings`` has to match with an existing database column.
+      The value for each key within ``options.databaseColumnMappings`` is an array with additional informations.
+
+      This mapping is done *before* the ``options.element`` mapping.
+      This means if you map a database column to a value through ``options.databaseColumnMappings`` and map a submitted
+      form element value to the same database column through ``options.element``, the submitted form element value
+      will override the value you set within ``options.databaseColumnMappings``.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.value:
+
+databaseColumnMappings.<databaseColumnName>.value
++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      string
+
+:aspect:`Mandatory`
+      Yes
+
+:aspect:`Default value`
+      undefined
+
+:aspect:`Description`
+      The value which will be written to the database column.
+      You can also use the :ref:`FormRuntime accessor feature<concepts-finishers-customfinisherimplementations-accessingoptions-formruntimeaccessor>` to access every getable property from the ``FormRuntime``
+      In short: use something like ``{<formElementIdentifier>}`` to get the value from the submitted form element with the identifier ``<formElementIdentifier>``.
+
+      If you use the FormRuntime accessor feature within ``options.databaseColumnMappings``, the functionality is nearly identical
+      to the ``options.elements`` configuration variant.
+
+
+.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.skipifvalueisempty:
+
+databaseColumnMappings.<databaseColumnName>.skipIfValueIsEmpty
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+:aspect:`Data type`
+      bool
+
+:aspect:`Mandatory`
+      No
+
+:aspect:`Default value`
+      false
+
+:aspect:`Description`
+      Set this to true if the database column should not be written if the value from ``options.databaseColumnMappings.<databaseColumnName>.value`` is empty.
diff --git a/typo3/sysext/form/Documentation/D/FormEditor/Index.rst b/typo3/sysext/form/Documentation/D/FormEditor/Index.rst
new file mode 100644
index 000000000000..6b52025495f3
--- /dev/null
+++ b/typo3/sysext/form/Documentation/D/FormEditor/Index.rst
@@ -0,0 +1,2691 @@
+.. include:: /Includes.rst.txt
+
+
+.. _apireference-formeditor:
+
+Form editor
+===========
+
+
+.. _apireference-formeditor-hooks:
+
+Hooks
+-----
+
+EXT:form implements various hooks so that forms can be manipulated while being
+created or saved.
+
+
+.. _apireference-formeditor-hooks-beforeformcreate:
+
+beforeFormCreate
+^^^^^^^^^^^^^^^^
+
+The form manager calls the 'beforeFormCreate' hook.
+
+
+.. _apireference-formeditor-hooks-beforeformcreate-connect:
+
+Connect to the hook
++++++++++++++++++++
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormCreate'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-formeditor-hooks-beforeformcreate-use:
+
+Use the hook
+++++++++++++
+
+::
+
+   /**
+    * @param string $formPersistenceIdentifier
+    * @param array $formDefinition
+    * @return array
+    */
+   public function beforeFormCreate(string $formPersistenceIdentifier, array $formDefinition): array
+   {
+       return $formDefinition;
+   }
+
+
+.. _apireference-formeditor-hooks-beforeformduplicate:
+
+beforeFormDuplicate
+^^^^^^^^^^^^^^^^^^^
+
+The form manager call the 'beforeFormDuplicate' hook.
+
+
+.. _apireference-formeditor-hooks-beforeformduplicate-connect:
+
+Connect to the hook
++++++++++++++++++++
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDuplicate'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-formeditor-hooks-beforeformduplicate-use:
+
+Use the hook
+++++++++++++
+
+::
+
+   /**
+    * @param string $formPersistenceIdentifier
+    * @param array $formDefinition
+    * @return array
+    */
+   public function beforeFormDuplicate(string $formPersistenceIdentifier, array $formDefinition): array
+   {
+       return $formDefinition;
+   }
+
+
+.. _apireference-formeditor-hooks-beforeformdelete:
+
+beforeFormDelete
+^^^^^^^^^^^^^^^^
+
+The form manager call the 'beforeFormDelete' hook.
+
+
+.. _apireference-formeditor-hooks-beforeformdelete-connect:
+
+Connect to the hook
++++++++++++++++++++
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDelete'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-formeditor-hooks-beforeformdelete-use:
+
+Use the hook
+++++++++++++
+
+::
+
+   /**
+    * @param string $formPersistenceIdentifier
+    * @return void
+    */
+   public function beforeFormDelete(string $formPersistenceIdentifier)
+   {
+   }
+
+
+.. _apireference-formeditor-hooks-beforeformsave:
+
+beforeFormSave
+^^^^^^^^^^^^^^
+
+The form editor call the 'beforeFormSave' hook.
+
+
+.. _apireference-formeditor-hooks-beforeformsave-connect:
+
+Connect to the hook
++++++++++++++++++++
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-formeditor-hooks-beforeformsave-use:
+
+Use the hook
+++++++++++++
+
+::
+
+   /**
+    * @param string $formPersistenceIdentifier
+    * @param array $formDefinition
+    * @return array
+    */
+   public function beforeFormSave(string $formPersistenceIdentifier, array $formDefinition): array
+   {
+       return $formDefinition;
+   }
+
+
+
+.. _apireference-formeditor-stage:
+
+Stage
+-----
+
+
+.. _apireference-formeditor-stage-commonabstractformelementtemplates:
+
+Common abstract view form element templates
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The basic idea of the ``abstract view`` is to give a quick overview of the
+configuration of form elements, without having to click them in order to view
+the detailed configuration in the ``Inspector``. The ``form editor`` requires
+for each form element an inline HTML template and the corresponding JavaScript
+code. Information matching inline HTML templates to the appropriate form
+elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
+At this point, the key identifying the form element follows a convention:
+``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
+``form editor`` which inline HTML template should be loaded for the respective
+form element. This template is then cloned via JavaScript, brought to life
+using the form element configuration and shown in the ``Stage`` component.
+
+You can read about how particular form elements are mapped to inline HTML
+templates and how the corresponding JavaScript code are executed :ref:`here <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`.
+
+The form element inline HTML templates and the corresponding JavaScript code
+are configured for reuse. In this way, most form elements you create should be
+able to access the components delivered in EXT:form, without requiring separate
+implementations (at least we hope so). For your own implementations, study
+EXT:form stage templates, which is found under ``Resources/Private/Backend/Partials/FormEditor/Stage/*``.
+The corresponding JavaScript code is found under ``Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js``.
+The method ``_renderTemplateDispatcher()`` shows, which methods will be used to
+render the respective form elements.
+
+Essentially, two different inline HTML templates exists that can be rendered
+with two different JavaScript methods, which are described below. The other
+inline HTML templates are almost all versions of these two basic variants and
+show extra/ other form-element information. The same applies to the
+corresponding JavaScript codes.
+
+
+.. _apireference-formeditor-stage-commonabstractformelementtemplates-simpletemplate:
+
+Stage/SimpleTemplate
+++++++++++++++++++++
+
+This template displays the ``label`` property of the form element. Depending on
+the JavaScript rendering method used, a validator icon will be shown on the
+right as soon as a validator is added to the form element. In this case, the
+used validator labels are likewise displayed, if the form element is selected
+and/ or the cursor hovers over the form element. This template should generally
+be enough for all possible, self-defined form elements.
+
+The ``Stage/SimpleTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
+with the method ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``.
+
+
+.. _apireference-formeditor-stage-commonabstractformelementtemplates-selecttemplate:
+
+Stage/SelectTemplate
+++++++++++++++++++++
+
+This template behaves like the ``Stage/SimpleTemplate`` except that it also
+shows the chosen options labels of the form elements. This is naturally only
+possible for form elements that have ``properties.options.*`` values, e.g.
+``MultiCheckbox``:
+
+.. code-block:: yaml
+
+       type: MultiCheckbox
+       identifier: multicheckbox-1
+       label: 'Multi checkbox'
+       properties:
+         options:
+           value1: label1
+           value2: label2
+
+The template will now list 'label1' and 'label2'.
+
+You can copy this template variant for your own form element, if that form-
+element template also lists array values, which, however, are not found under
+``properties.options.*``. For this purpose, the 'Stage/FileUploadTemplate' is
+an example. It is basically the 'Stage/SelectTemplate' template, with one
+altered property.
+
+In the ``FileUpload`` form element, multiple property values are available
+under ``properties.allowedMimeTypes.*`` as an array.
+
+.. code-block:: yaml
+
+       type: FileUpload
+       identifier: fileupload-1
+       label: 'File upload'
+       properties:
+         saveToFileMount: '1:/user_upload/'
+         allowedMimeTypes:
+           - application/msexcel
+           - application/pdf
+
+Stage/SelectTemplate
+
+.. code-block:: html
+
+   <div data-identifier="multiValueContainer" data-template-property="properties.options">
+
+Stage/FileUploadTemplate
+
+.. code-block:: html
+
+   <div data-identifier="multiValueContainer" data-template-property="properties.allowedMimeTypes">
+
+``data-template-property`` contains the path to the property, which is to be
+read out of the form element and then shown in the template.
+
+The ``Stage/SelectTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
+with the method ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts:
+
+Basic JavaScript Concepts
+-------------------------
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events:
+
+Events
+^^^^^^
+
+EXT:form implements the ``publish/subscribe pattern`` to put the event handling
+into effect. To learn more about this pattern, you should read
+https://addyosmani.com/resources/essentialjsdesignpatterns/book/.
+Note that the order of the subscriber is not manipulable and that information
+flow between the subscribers does not exist. All events must be asynchronously
+designed.
+
+Publish an event:
+
+.. code-block:: javascript
+
+   getPublisherSubscriber().publish('eventname', [argumentToPublish1, argumentToPublish2, ...]);
+
+Subscribe to an event:
+
+.. code-block:: javascript
+
+   var subscriberToken = getPublisherSubscriber().subscribe('eventname', function(topic, args) {
+       // args[0] = argumentToPublish1
+       // args[1] = argumentToPublish2
+       // ...
+   });
+
+Unsubscribe an event subscriber:
+
+.. code-block:: javascript
+
+   getPublisherSubscriber().unsubscribe(subscriberToken);
+
+EXT:form itself publishes and subscribes to the following events:
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-ajax-beforesend:
+
+ajax/beforeSend
++++++++++++++++
+
+Each Ajax request is called before this event is sent. EXT:form uses this event
+to display the spinner icon on the save button.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('ajax/beforeSend', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-ajax-complete:
+
+ajax/complete
++++++++++++++
+
+Each Ajax request is called after the end of this event. EXT:form uses this
+event to remove the spinner icon on the save button.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('ajax/complete', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-error:
+
+core/ajax/error
++++++++++++++++
+
+This event is called if the Ajax request, which is used to save the form or to
+render the current page of the form in the ``preview view``, fails. EXT:form
+uses this event to show an error message as a flash message and to show the
+received error text in the ``preview view``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = jqXHR
+    *              args[1] = textStatus
+    *              args[2] = errorThrown
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/ajax/error', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-renderformdefinitionpage-success:
+
+core/ajax/renderFormDefinitionPage/success
+++++++++++++++++++++++++++++++++++++++++++
+
+This event is called if the Ajax request that is used to render the current
+page of the form in the ``preview view`` was successful. EXT:form uses this
+event to display the rendered form in the ``preview view``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = html
+    *              args[1] = pageIndex
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-saveformdefinition-success:
+
+core/ajax/saveFormDefinition/success
+++++++++++++++++++++++++++++++++++++
+
+This event is called if the Ajax request that is used to save the form was
+successful. EXT:form uses this event to display a success message as a flash
+message. The ``form editor`` is also informed that no unsaved content currently
+exists.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = html
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-applicationstate-add:
+
+core/applicationState/add
++++++++++++++++++++++++++
+
+The addition/ deletion and movement of form elements und property collection
+elements (validators/ finishers) is saved in an internal stack so that the
+undo/ redo function can be implemented. This event is called whenever the
+current state is added to the stack. EXT:form uses this event to reset the
+enabled/ disabled state of the undo/ redo buttons.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = applicationState
+    *              args[1] = stackPointer
+    *              args[2] = stackSize
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/applicationState/add', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-currentlyselectedformelementchanged:
+
+core/currentlySelectedFormElementChanged
+++++++++++++++++++++++++++++++++++++++++
+
+The method ``getFormEditorApp().setCurrentlySelectedFormElement()`` tells the
+``form editor`` which form element should currently be dealt with. This method
+calls this event at the end.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/currentlySelectedFormElementChanged', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged:
+
+core/formElement/somePropertyChanged
+++++++++++++++++++++++++++++++++++++
+
+Each :ref:`FormElement model<apireference-formeditor-basicjavascriptconcepts-formelementmodel>`
+can write properties into the ``FormElement model`` through the methods ``get``
+and ``set``. Each property path can register an event name for the publisher
+through the method ``on``. This event is then always called when a property
+path is written via ``set``. Read :ref:`FormElement model<concepts-formeditor-basicjavascriptconcepts-formelementmodel>`
+for more information. EXT:form automatically registers for all known property
+paths of a form element the event ``core/formElement/somePropertyChanged``.
+This means that every property written via ``set`` calls this event. Among
+other things, EXT:form uses this event for, for example, updating the label of
+a form element in other components (e.g. ``Tree`` component ) when this label
+is changed. Furthermore, any validation errors from form element properties
+are indicated by this event in the ``Tree`` component.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = propertyPath
+    *              args[1] = value
+    *              args[2] = oldValue
+    *              args[3] = formElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-moved:
+
+view/collectionElement/moved
+++++++++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``
+calls this event at the end. EXT:form uses this event to re-render the
+``Inspector`` component as soon as a property collection element (validator/
+finisher) is moved.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = movedCollectionElementIdentifier
+    *              args[1] = previousCollectionElementIdentifier
+    *              args[2] = nextCollectionElementIdentifier
+    *              args[3] = collectionName
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/collectionElement/moved', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-new-added:
+
+view/collectionElement/new/added
+++++++++++++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``
+calls this event at the end. EXT:form uses this event to re-render the
+``Inspector`` component as soon as a property collection element (validator/
+finisher) is created and added.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    *              args[2] = formElement
+    *              args[3] = collectionElementConfiguration
+    *              args[4] = referenceCollectionElementIdentifier
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/collectionElement/new/added', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-removed:
+
+view/collectionElement/removed
+++++++++++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``
+calls this event at the end. EXT:form uses this event to re-render the
+``Inspector`` component as soon as a property collection element (validator/
+finisher) is removed.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    *              args[2] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/collectionElement/removed', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted:
+
+view/formElement/inserted
++++++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().createAndAddFormElement()`` and
+the event :ref:`view/insertElements/perform/after<apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after>`
+call this event at the end. EXT:form uses this event to set the current
+to-be-processed form element (``getFormEditorApp().setCurrentlySelectedFormElement()``)
+and to re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = newFormElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/formElement/inserted', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-moved:
+
+view/formElement/moved
+++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().moveFormElement()`` calls this
+event at the end.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = movedFormElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/formElement/moved', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-removed:
+
+view/formElement/removed
+++++++++++++++++++++++++
+
+The method ``getFormEditorApp().getViewModel().removeFormElement()`` calls this
+event at the end. EXT:form uses this event to set the current to-be-processed
+form element (``getFormEditorApp().setCurrentlySelectedFormElement()``) and to
+re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = parentFormElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/formElement/removed', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-close-clicked:
+
+view/header/button/close/clicked
+++++++++++++++++++++++++++++++++
+
+The onClick event of the "Close" button in the ``form editor's`` header section
+calls this event. EXT:form uses this event to display a warning message in case
+there are unsaved changes.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/header/button/close/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-newpage-clicked:
+
+view/header/button/newPage/clicked
+++++++++++++++++++++++++++++++++++
+
+The onClick event of the "new page" button in the ``form editor's`` header
+section calls this event. EXT:form uses this event to display the "new page"
+dialog box.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = targetEvent
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-save-clicked:
+
+view/header/button/save/clicked
++++++++++++++++++++++++++++++++
+
+The onClick event of the "save" button in the ``form editor's`` header section
+calls this event. EXT:form uses this event either to display a dialog box with
+the element in question (if there are validation errors) or to save the ``form
+definition`` (if there are no validation errors).
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/header/button/save/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-formsettings-clicked:
+
+view/header/formSettings/clicked
+++++++++++++++++++++++++++++++++
+
+The onClick event of the "settings"  button in the ``form editor's`` header
+section calls this event. EXT:form uses this event to select the root form
+element.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/header/formSettings/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after:
+
+view/insertElements/perform/after
++++++++++++++++++++++++++++++++++
+
+This event is called from the "new element" dialog box upon selection of a form
+element:
+
+- if "After" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
+- if the "Create new element" button in the form-element toolbar for non-composite elements is clicked.
+
+EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``)
+and then move (``getFormEditorApp().getViewModel().moveFormElement()``) it
+below the currently selected element (sibling). At the end of this event, the
+event :ref:`view/formElement/inserted<apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted>`
+is called. The event ``view/formElement/inserted`` in ``getFormEditorApp().getViewModel().createAndAddFormElement()``
+was previously deactivated.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementType
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/insertElements/perform/after', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-bottom:
+
+view/insertElements/perform/bottom
+++++++++++++++++++++++++++++++++++
+
+This event is called from the "new element" dialog box upon selection of a form
+element:
+
+- if, in the ``abstract view`` mode, the "Create new element" button at the end of the ``Stage`` component is clicked.
+
+EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
+This element is always created as the last element of the currently selected
+page.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementType
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-inside:
+
+view/insertElements/perform/inside
+++++++++++++++++++++++++++++++++++
+
+This event is called from the "new element" dialog box upon selection of a form
+element:
+
+- if "Inside" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
+
+EXT:form uses this event to create a new form element as a child element of the
+currently selected element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementType
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/insertElements/perform/inside', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertpages-perform:
+
+view/insertPages/perform
+++++++++++++++++++++++++
+
+This event is called from the "new element" dialog box upon selection of a page
+element:
+
+- if the "Create new page" icon in the header section is clicked.
+- if the "Create new page" button in the ``Tree`` component is clicked.
+
+EXT:form uses this event to create a new page after the currently selected page
+(``getFormEditorApp().getViewModel().createAndAddFormElement()``).
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementType
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/insertPages/perform', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-existing-selected:
+
+view/inspector/collectionElement/existing/selected
+++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
+and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
+are used to display the available validators/ finishers for a form element as a
+select box. Furthermore, these ``inspector editors`` indicate that in the
+``form definition``, validators/ finishers for the currently selected element
+already exist. This occurs through the event ``view/inspector/collectionElement/existing/selected``.
+EXT:form uses this event to render these validators/ finishers and their
+tentatively configured ``inspector editors`` (``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``).
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-new-selected:
+
+view/inspector/collectionElement/new/selected
++++++++++++++++++++++++++++++++++++++++++++++
+
+The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
+and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
+are used to display the available validators/ finishers for a form element as a
+select box. The onChange event of the select box then calls this event. In
+addition, the ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
+calls this event when a checkbox is chosen. EXT:form uses this event to add and
+render the validator/ finisher of the ``form definition`` via ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-dnd-update:
+
+view/inspector/collectionElements/dnd/update
+++++++++++++++++++++++++++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
+the ``view/inspector/collectionElements/dnd/update`` event if a property
+collection element in the ``Inspector`` component is sorted. EXT:form uses this
+event to move the validator/ finisher in the ``form definition`` via the method
+``getFormEditorApp().getViewModel().movePropertyCollectionElement()``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = movedCollectionElementIdentifier
+    *              args[1] = previousCollectionElementIdentifier
+    *              args[2] = nextCollectionElementIdentifier
+    *              args[3] = collectionName
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-editor-insert-perform:
+
+view/inspector/editor/insert/perform
+++++++++++++++++++++++++++++++++++++
+
+The methods ``getFormEditorApp().getViewModel().renderInspectorEditors()`` (to
+render all ``inspector editors`` for a form element) and ``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``
+(to render the ``inspector editors`` for a validator/ finisher) call this event
+at the end. Strictly speaking, the ``Inspector`` component in the method
+``_renderEditorDispatcher()`` calls this event.
+Each ``inspector editor`` has the property :ref:`templateName <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.templatename>`,
+which gives the ``form editor`` two pieces of information. On the one hand the
+``templateName`` must match with a key within the :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
+The ``form editor`` can consequently load a corresponding inline HTML template
+for the ``inspector editor``. On the other hand, the ``Inspector`` component
+must be told which JavaScript code should be executed for the
+``inspector editor``. For the ``inspector editors`` delivered with EXT:form,
+this occurs within the method ``_renderEditorDispatcher()``.
+An existing hard-coded list of known ``inspector editors`` determines, by means
+of the property ``templateName``, which corresponding JavaScript method should
+be executed for the ``inspector editor``. At the end, the event
+``view/inspector/editor/insert/perform`` is called. If you wish to implement
+your own ``inspector editor``, you can use this event to execute in
+:ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
+the corresponding JavaScript code, with the help of the property
+``templateName``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = editorConfiguration
+    *              args[1] = editorHtml
+    *              args[2] = collectionElementIdentifier
+    *              args[3] = collectionName
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
+   });
+
+A simple example that registers a custom ``inspector editor`` called 'Inspector-MyCustomInspectorEditor' and adds it to text form elements:
+
+.. code-block:: yaml
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formEditor:
+               dynamicJavaScriptModules:
+                 additionalViewModelModules:
+                   10: 'TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel'
+               formEditorFluidConfiguration:
+                 partialRootPaths:
+                   100: 'EXT:my_site_package/Resources/Private/Backend/Partials/FormEditor/'
+               formEditorPartials:
+                 Inspector-MyCustomInspectorEditor: 'Inspector/MyCustomInspectorEditor'
+             formElementsDefinition:
+               Text:
+                 formEditor:
+                   editors:
+                     600:
+                       templateName: 'Inspector-MyCustomInspectorEditor'
+                       ...
+
+.. code-block:: javascript
+   :emphasize-lines: 107-116
+
+   /**
+    * Module: @typo3/my-site-package/backend/form-editor/view-model
+    */
+   define(['jquery',
+           'TYPO3/CMS/Form/Backend/FormEditor/Helper'
+           ], function($, Helper) {
+           'use strict';
+
+       return (function($, Helper) {
+
+           /**
+            * @private
+            *
+            * @var object
+            */
+           var _formEditorApp = null;
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getFormEditorApp() {
+               return _formEditorApp;
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getPublisherSubscriber() {
+               return getFormEditorApp().getPublisherSubscriber();
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getUtility() {
+               return getFormEditorApp().getUtility();
+           };
+
+           /**
+            * @private
+            *
+            * @param object
+            * @return object
+            */
+           function getHelper() {
+               return Helper;
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getCurrentlySelectedFormElement() {
+               return getFormEditorApp().getCurrentlySelectedFormElement();
+           };
+
+           /**
+            * @private
+            *
+            * @param mixed test
+            * @param string message
+            * @param int messageCode
+            * @return void
+            */
+           function assert(test, message, messageCode) {
+               return getFormEditorApp().assert(test, message, messageCode);
+           };
+
+           /**
+            * @private
+            *
+            * @return void
+            * @throws 1491643380
+            */
+           function _helperSetup() {
+               assert('function' === $.type(Helper.bootstrap),
+                   'The view model helper does not implement the method "bootstrap"',
+                   1491643380
+               );
+               Helper.bootstrap(getFormEditorApp());
+           };
+
+           /**
+            * @private
+            *
+            * @return void
+            */
+           function _subscribeEvents() {
+               /**
+                * @private
+                *
+                * @param string
+                * @param array
+                *              args[0] = editorConfiguration
+                *              args[1] = editorHtml
+                *              args[2] = collectionElementIdentifier
+                *              args[3] = collectionName
+                * @return void
+                */
+               getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
+                   if (args[0]['templateName'] === 'Inspector-MyCustomInspectorEditor') {
+                       renderMyCustomInspectorEditor(
+                           args[0],
+                           args[1],
+                           args[2],
+                           args[3]
+                       );
+                   }
+               });
+           };
+
+           /**
+            * @private
+            *
+            * @param object editorConfiguration
+            * @param object editorHtml
+            * @param string collectionElementIdentifier
+            * @param string collectionName
+            * @return void
+            */
+           function renderMyCustomInspectorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
+               // do cool stuff
+           });
+
+           /**
+            * @public
+            *
+            * @param object formEditorApp
+            * @return void
+            */
+           function bootstrap(formEditorApp) {
+               _formEditorApp = formEditorApp;
+               _helperSetup();
+               _subscribeEvents();
+           };
+
+           /**
+            * Publish the public methods.
+            * Implements the "Revealing Module Pattern".
+            */
+           return {
+               bootstrap: bootstrap
+           };
+       })($, Helper);
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-removecollectionelement-perform:
+
+view/inspector/removeCollectionElement/perform
+++++++++++++++++++++++++++++++++++++++++++++++
+
+The ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
+calls this event, if the checkbox is deselected. EXT:form uses this event to
+remove the configured required validator ('NotEmpty') from the ``form
+definition`` through the method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    *              args[2] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-close-perform:
+
+view/modal/close/perform
+++++++++++++++++++++++++
+
+If you try to close the ``form editor`` with unsaved content, a dialog box
+appears, asking whether you really wish to close it. If you confirm it, this
+event is called in the ``check box`` component. EXT:form uses this event to
+close the ``form editor`` and return to the ``form manager``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/modal/close/perform', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removecollectionelement-perform:
+
+view/modal/removeCollectionElement/perform
+++++++++++++++++++++++++++++++++++++++++++
+
+If you try to remove a validator/ finisher by clicking the remove icon, a
+dialog box appears, asking you to confirm this action. If confirmed, this event
+is called in the ``check box`` component. EXT:form uses this event to remove
+the validator/ finisher from the ``form definition`` through the method
+``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = collectionElementIdentifier
+    *              args[1] = collectionName
+    *              args[2] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/modal/removeCollectionElement/perform', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removeformelement-perform:
+
+view/modal/removeFormElement/perform
+++++++++++++++++++++++++++++++++++++
+
+If you try to remove a form element by clicking the remove icon, a dialog box
+appears, asking you to confirm this action. If confirmed, this event is called
+in the ``check box`` component. EXT:form uses this event to remove the form
+element from the ``form definition`` via the method ``getFormEditorApp().getViewModel().removeFormElement()``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/modal/removeFormElement/perform', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-validationerrors-element-clicked:
+
+view/modal/validationErrors/element/clicked
++++++++++++++++++++++++++++++++++++++++++++
+
+If a form element contains a validation error and you try to save the form, a
+dialog box appears, listing all form elements with validation errors. One such
+form element can be clicked in this dialog box. This event is called by
+clicking a form element in the dialog box. EXT:form uses this event to select
+and show this form element.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/modal/validationErrors/element/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationnext-clicked:
+
+view/paginationNext/clicked
++++++++++++++++++++++++++++
+
+This event is called if the 'pagination next' button in the ``Stage``
+component's header section is clicked. EXT:form uses this event to render the
+next page of the form.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/paginationNext/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationprevious-clicked:
+
+view/paginationPrevious/clicked
++++++++++++++++++++++++++++++++
+
+This event is called, if the 'pagination previous' button in the ``Stage``
+component's header section is clicked. EXT:form uses this event to render the
+previous page of the form.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/paginationPrevious/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-ready:
+
+view/ready
+++++++++++
+
+EXT:form makes it possible to load :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
+If all modules are loaded, the view-model method ``_loadAdditionalModules``
+calls this event. EXT:form uses this event to remove the preloader icon and
+finally initialize the ``form editor``.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/ready', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-redobutton-clicked:
+
+view/redoButton/clicked
++++++++++++++++++++++++
+
+This event is called if the redo button in the ``form editor`` header is
+clicked. The addition/ deletion and movement of form elements and property
+collection elements (validators/ finishers) is saved in an internal stack in
+order to reset the undo/ redo functionality. EXT:form uses this event to reset
+this stack to the previous state.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/redoButton/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-button-newelement-clicked:
+
+view/stage/abstract/button/newElement/clicked
++++++++++++++++++++++++++++++++++++++++++++++
+
+This event is called if the "Create new element" button at the end of the
+``Stage`` component in the ``abstract view`` mode is clicked. EXT:form uses
+this event to display the "new element" dialog box.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = targetEvent
+    *              args[1] = configuration
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/button/newElement/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-change:
+
+view/stage/abstract/dnd/change
+++++++++++++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'change' event from 'jquery.mjs.nestedSortable' calls
+the ``view/stage/abstract/dnd/change`` event in the ``Stage`` component in the
+``abstract view`` mode if form elements are sorted. EXT:form uses this event to
+set various CSS classes during the drag-and-drop process.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = placeholderDomElement
+    *              args[1] = parentFormElementIdentifierPath
+    *              args[2] = enclosingCompositeFormElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/change', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-start:
+
+view/stage/abstract/dnd/start
++++++++++++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'start' event from 'jquery.mjs.nestedSortable' calls
+the ``view/stage/abstract/dnd/start`` event in the ``Stage`` component in the
+``abstract view`` mode if form elements are sorted. EXT:form uses this event to
+set various CSS classes at the start of the drag-and-drop process.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = draggedFormElementDomElement
+    *              args[1] = draggedFormPlaceholderDomElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/start', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-stop:
+
+view/stage/abstract/dnd/stop
+++++++++++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'stop' event from 'jquery.mjs.nestedSortable' calls the
+``view/stage/abstract/dnd/stop`` event in the ``Stage`` component in the
+``abstract view`` mode if form elements are sorted. EXT:form uses this event to
+to re-render the ``Tree``, ``Stage`` and ``Inspector`` components at the end of
+the drag-and-drop process and to select the moved form element.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = draggedFormElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/stop', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-update:
+
+view/stage/abstract/dnd/update
+++++++++++++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
+the ``view/stage/abstract/dnd/update`` event in the ``Stage`` component in the
+``abstract view`` mode if form elements are sorted. EXT:form uses this event
+to move the form element in the ``form definition`` accordingly at the end of
+the drag-and-drop process.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = movedDomElement
+    *              args[1] = movedFormElementIdentifierPath
+    *              args[2] = previousFormElementIdentifierPath
+    *              args[3] = nextFormElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/update', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-elementtoolbar-button-newelement-clicked:
+
+view/stage/abstract/elementToolbar/button/newElement/clicked
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+This event is called if the "Create new element" button in the form-element
+toolbar or "Inside" or "After" in the split button is clicked. EXT:form uses
+this event to display the "New element" dialog box.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = targetEvent
+    *              args[1] = configuration
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/elementToolbar/button/newElement/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-postprocess:
+
+view/stage/abstract/render/postProcess
+++++++++++++++++++++++++++++++++++++++
+
+This event is called after the ``abstract view`` of the ``Stage`` component has
+been rendered. EXT:form uses this event to render the undo/ redo buttons.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/render/postProcess', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-preprocess:
+
+view/stage/abstract/render/preProcess
++++++++++++++++++++++++++++++++++++++
+
+This event is called before the ``abstract view`` of the ``Stage`` component is
+rendered.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/render/preProcess', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform:
+
+view/stage/abstract/render/template/perform
++++++++++++++++++++++++++++++++++++++++++++
+
+The methods ``getFormEditorApp().getViewModel().renderAbstractStageArea()``
+call this event. Strictly speaking, the ``Stage`` component in the method
+``_renderTemplateDispatcher()`` calls this event. The ``form editor`` requires
+for each form element an inline HTML template the corresponding JavaScript
+code. Information matching inline HTML templates to the appropriate form
+elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
+At this point, the key identifying the form element follows a convention:
+``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
+``form editor`` which inline HTML template should be loaded for the respective
+form element. The ``_renderTemplateDispatcher()`` method then identifies, by
+means of the form element's ``<formElementTypeIdentifier>``, the corresponding
+JavaScript code to fill the inline HTML template with life.
+``_renderTemplateDispatcher()`` contains a hard-coded list with the
+``<formElementTypeIdentifier>`` that is brought in with the EXT:form, and it
+renders the inline HTML templates accordingly. At the end, the
+``view/stage/abstract/render/template/perform`` event is called. If you wish to
+implement your own form element and show it in the ``form editor``, this event
+can be used to execute in :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`
+the corresponding JavaScript code, with the help of the ``<formElementTypeIdentifier>``.
+This is generally enough to allow the ``Stage/SimpleTemplate`` and/ or
+``Stage/SelectTemplate`` inline HTML template to be rendered for your own form
+element and, in the JavaScript code, to access the ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``
+and/ or ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``
+method delivered with EXT:form. An overview over the functionality of the
+formEditorPartials for the ``<formElementTypeIdentifier>`` and its JavaScript
+code is found :ref:`here <apireference-formeditor-stage-commonabstractformelementtemplates>`.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElement
+    *              args[1] = template
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/abstract/render/template/perform', function(topic, args) {
+   });
+
+A simple example reusing the EXT:form inline HTML template ``Stage/SelectTemplate`` and the EXT:form JavaScript code ``renderSelectTemplates()``
+for a custom form element with ``<formElementTypeIdentifier>`` = 'GenderSelect'.
+In this example, 'GenderSelect' is basically a radio button form element with some predefined options.
+
+.. code-block:: yaml
+   :emphasize-lines: 11
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formEditor:
+               dynamicJavaScriptModules:
+                 additionalViewModelModules:
+                   10: '@typo3/my-site-package/backend/form-editor/view-model.js'
+               formEditorPartials:
+                 FormElement-GenderSelect: 'Stage/SelectTemplate'
+             formElementsDefinition:
+               GenderSelect:
+                 __inheritances:
+                   10: 'TYPO3.CMS.Form.prototypes.standard.formElementsDefinition.RadioButton'
+                 renderingOptions:
+                   templateName: 'RadioButton'
+                 properties:
+                   options:
+                     f: 'Female'
+                     m: 'Male'
+                     u: 'Unicorn'
+                     a: 'Alien'
+                 formEditor:
+                   label: 'Gender Select'
+                   group: select
+                   groupSorting: 9000
+                   predefinedDefaults:
+                     properties:
+                       options:
+                         f: 'Female'
+                         m: 'Male'
+                         u: 'Unicorn'
+                         a: 'Alien'
+                   editors:
+                     300: null
+
+.. code-block:: javascript
+   :emphasize-lines: 105-109
+
+   /**
+    * Module: @typo3/my-site-package/backend/form-editor/view-model
+    */
+   define(['jquery',
+           'TYPO3/CMS/Form/Backend/FormEditor/Helper'
+           ], function($, Helper) {
+           'use strict';
+
+       return (function($, Helper) {
+
+           /**
+            * @private
+            *
+            * @var object
+            */
+           var _formEditorApp = null;
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getFormEditorApp() {
+               return _formEditorApp;
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getPublisherSubscriber() {
+               return getFormEditorApp().getPublisherSubscriber();
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getUtility() {
+               return getFormEditorApp().getUtility();
+           };
+
+           /**
+            * @private
+            *
+            * @param object
+            * @return object
+            */
+           function getHelper() {
+               return Helper;
+           };
+
+           /**
+            * @private
+            *
+            * @return object
+            */
+           function getCurrentlySelectedFormElement() {
+               return getFormEditorApp().getCurrentlySelectedFormElement();
+           };
+
+           /**
+            * @private
+            *
+            * @param mixed test
+            * @param string message
+            * @param int messageCode
+            * @return void
+            */
+           function assert(test, message, messageCode) {
+               return getFormEditorApp().assert(test, message, messageCode);
+           };
+
+           /**
+            * @private
+            *
+            * @return void
+            * @throws 1491643380
+            */
+           function _helperSetup() {
+               assert('function' === $.type(Helper.bootstrap),
+                   'The view model helper does not implement the method "bootstrap"',
+                   1491643380
+               );
+               Helper.bootstrap(getFormEditorApp());
+           };
+
+           /**
+            * @private
+            *
+            * @return void
+            */
+           function _subscribeEvents() {
+               /**
+                * @private
+                *
+                * @param string
+                * @param array
+                *              args[0] = formElement
+                *              args[1] = template
+                * @return void
+                */
+               getPublisherSubscriber().subscribe('view/stage/abstract/render/template/perform', function(topic, args) {
+                   if (args[0].get('type') === 'GenderSelect') {
+                       getFormEditorApp().getViewModel().getStage().renderSelectTemplates(args[0], args[1]);
+                   }
+               });
+           };
+
+           /**
+            * @public
+            *
+            * @param object formEditorApp
+            * @return void
+            */
+           function bootstrap(formEditorApp) {
+               _formEditorApp = formEditorApp;
+               _helperSetup();
+               _subscribeEvents();
+           };
+
+           /**
+            * Publish the public methods.
+            * Implements the "Revealing Module Pattern".
+            */
+           return {
+               bootstrap: bootstrap
+           };
+       })($, Helper);
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-element-clicked:
+
+view/stage/element/clicked
+++++++++++++++++++++++++++
+
+This event is called from the ``Stage`` component when a form element is
+clicked. EXT:form uses this event to select this element and to display the
+form-element toolbar. In addition, the ``Tree`` and ``Inspector`` components
+are re-rendered.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/element/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-panel-clicked:
+
+view/stage/panel/clicked
+++++++++++++++++++++++++
+
+This event is called if the header section of the ``Stage`` component is
+clicked.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/panel/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-preview-render-postprocess:
+
+view/stage/preview/render/postProcess
++++++++++++++++++++++++++++++++++++++
+
+This event is called after the ``preview view`` of the ``Stage`` component has
+been rendered. EXT:form uses this event to render the undo/ redo buttons.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/stage/preview/render/postProcess', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-button-newpage-clicked:
+
+view/structure/button/newPage/clicked
++++++++++++++++++++++++++++++++++++++
+
+This event is called from the onClick event of the ``Tree`` component's "Create
+new page" button. EXT:form uses this event to display the "new page" dialog
+box.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = targetEvent
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/structure/button/newPage/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-renew-postprocess:
+
+view/structure/renew/postProcess
+++++++++++++++++++++++++++++++++
+
+This event is called from the view-model after the ``Tree`` component has been
+re-rendered. EXT:form uses this event to display potential validation errors
+from form elements in the ``Tree`` component.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/structure/renew/postProcess', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-root-selected:
+
+view/structure/root/selected
+++++++++++++++++++++++++++++
+
+This event is called if the root form element in the ``Tree`` component is
+clicked. EXT:form uses this event to re-render the ``Stage``, ``Inspector`` and
+``Tree`` components.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/structure/root/selected', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-change:
+
+view/tree/dnd/change
+++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'change' event from 'jquery.mjs.nestedSortable' calls
+the ``view/tree/dnd/change`` event in der ``Tree`` component if form elements
+are sorted. EXT:form uses this event to set various CSS classes during the drag
+-and-drop process.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = placeholderDomElement
+    *              args[1] = parentFormElementIdentifierPath
+    *              args[2] = enclosingCompositeFormElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/tree/dnd/change', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-stop:
+
+view/tree/dnd/stop
+++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'stop' event from 'jquery.mjs.nestedSortable' calls the
+``view/tree/dnd/stop`` event in the ``Tree`` component if form elements are
+sorted. EXT:form uses this event to re-render ``Tree``, ``Stage`` and
+``Inspector`` components at the end of the drag-and-drop process and to select
+the moved form element.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = draggedFormElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/tree/dnd/stop', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-update:
+
+view/tree/dnd/update
+++++++++++++++++++++
+
+EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
+drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
+the ``view/tree/dnd/update`` event in der ``Tree`` component if form elements
+are sorted. EXT:form uses this event to move the form element in the ``form
+definition`` accordingly at the end of the drag-and-drop process.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = movedDomElement
+    *              args[1] = movedFormElementIdentifierPath
+    *              args[2] = previousFormElementIdentifierPath
+    *              args[3] = nextFormElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/tree/dnd/update', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-node-clicked:
+
+view/tree/node/clicked
+++++++++++++++++++++++
+
+This event is called from the ``Tree`` component if a form element is clicked.
+EXT:form uses this event to re-render the ``Stage`` and ``Inspector``
+components and select the form element.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = formElementIdentifierPath
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/tree/node/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-render-listitemadded:
+
+view/tree/render/listItemAdded
+++++++++++++++++++++++++++++++
+
+This event is called by the ``Tree`` component for each form element as soon as
+it is added to the tree.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    *              args[0] = listItem
+    *              args[1] = formElement
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/tree/render/listItemAdded', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-undobutton-clicked:
+
+view/undoButton/clicked
++++++++++++++++++++++++
+
+This event is called when the undo button is clicked in the ``form editor``
+header. The history of adding / deleting and moving form elements and property
+collection elements (validators/ finishers) is stored in an internal stack to
+implement the undo / redo functionality. EXT:form uses this event to set this
+stack to the next state.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/undoButton/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-viewmodebutton-abstract-clicked:
+
+view/viewModeButton/abstract/clicked
+++++++++++++++++++++++++++++++++++++
+
+This event is called when the abstract view button is clicked in the header
+area of the ``Stage`` component. EXT:form uses this event to render the
+``abstract view`` in the ``Stage`` component.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/viewModeButton/abstract/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-events-view-viewmodebutton-preview-clicked:
+
+view/viewModeButton/preview/clicked
++++++++++++++++++++++++++++++++++++
+
+This event is called when the preview button is clicked in the header area of
+the ``Stage`` component. EXT:form uses this event to render the ``preview
+view`` in the ``Stage`` component.
+
+Subscribe to the event:
+
+.. code-block:: javascript
+
+   /**
+    * @private
+    *
+    * @param string
+    * @param array
+    * @return void
+    */
+   getPublisherSubscriber().subscribe('view/viewModeButton/preview/clicked', function(topic, args) {
+   });
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel:
+
+FormElement model
+^^^^^^^^^^^^^^^^^
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-parentrenderable:
+
+Property: __parentRenderable
+++++++++++++++++++++++++++++
+
+__parentRenderable includes the parent element as ``FormElement model``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-identifierpath:
+
+Property: __identifierPath
+++++++++++++++++++++++++++
+
+Internally, all form elements are identified by their 'identifier' property,
+which must be unique for each form. The ``__identifierPath`` property contains
+the path to the element (as seen from the first element), separated by a ``/``.
+Using this path, you can access the element directly through an API method.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get:
+
+Method: get()
++++++++++++++
+
+Each property of the ``FormElement model`` can be accessed by the ``get()``
+method through the property path (separated by ``.``). Prerequisite for this
+is that all levels up to the target property are objects.
+
+Example of a ``FormElement model``:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {
+         "placeholder": "Name"
+       }
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "NotEmpty"
+       }
+     ]
+   }
+
+Access to ``properties.fluidAdditionalAttributes.placeholder``:
+
+.. code-block:: javascript
+
+   // value = 'Name'
+   var value = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').get('properties.fluidAdditionalAttributes.placeholder');
+
+Two exceptions are the two arrays of "finishers" / "validators" (``property
+collections``) and the ``renderables``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties:
+
+Accessing property collection properties
+''''''''''''''''''''''''''''''''''''''''
+
+Property collection are identified as form elements through the property
+``identifier``. Because property collection properties are in an array and
+their positions in the array are potentially unknown, the ``getFormEditorApp().buildPropertyPath()``
+method exists. This can be used to access a property of a property collection
+item via its ``identifier``.
+
+Example of a ``FormElement model``:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {
+         "placeholder": "Name"
+       }
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "StringLength"
+         "options": {
+           "minimum": "1",
+           "maximum": "2"
+         }
+       }
+     ]
+   }
+
+Access to ``options.minimum`` of the validator ``StringLength``:
+
+.. code-block:: javascript
+
+   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
+   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
+   // value = 1
+   var value = formElement.get(propertyPath);
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-renderables:
+
+Accessing renderables
+'''''''''''''''''''''
+
+Like ``property collections``, ``renderables`` (the child elements) are also in
+an array and their position in the array is potentially unknown. Direct access
+to child elements through the  ``get()`` method is impossible.
+``formElement.get('renderables')`` supplies an array with the ``FormElement
+models`` of the child elements. You must then loop over this array. Access to a
+specific child element should be done using ``getFormEditorApp().getFormElementByIdentifierPath()``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set:
+
+Method: set()
++++++++++++++
+
+Any property of the ``FormElement model`` can be written using the ``set()``
+method by means of the property path (separated by ``.``).
+
+Example of a ``FormElement model``:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {
+         "placeholder": "Name"
+       }
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "NotEmpty"
+       }
+     ]
+   }
+
+Set the property ``properties.fluidAdditionalAttributes.placeholder``:
+
+.. code-block:: javascript
+
+   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
+
+Example of the ``FormElement model`` after the ``set()`` operation:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {
+         "placeholder": "New Placeholder"
+       }
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "NotEmpty"
+       }
+     ]
+   }
+
+Two exceptions are the two arrays of "finishers" / "validators" (``property
+collections``) and the ``renderables``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-propertycollectionproperties:
+
+Setting property collection properties
+''''''''''''''''''''''''''''''''''''''
+
+In principle, the same applies here as for :ref:`get property collection properties<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties>`.
+
+Set the property ``options.minimum`` of the validator ``StringLength``:
+
+.. code-block:: javascript
+
+   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
+   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
+   formElement.set(propertyPath, '2');
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-renderables:
+
+Setting renderables
+'''''''''''''''''''
+
+To add child form elements to a ``FormElement model``, the appropriate API
+methods should be used:
+
+- getFormEditorApp().createAndAddFormElement()
+- getFormEditorApp().addFormElement()
+- getFormEditorApp().moveFormElement()
+- getFormEditorApp().removeFormElement()
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset:
+
+Method: unset()
++++++++++++++++
+
+Any property of the ``FormElement model`` can be deleted using the method
+``unset()`` by means of the property path (separated by ``.``).
+
+Example of a ``FormElement model``:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {
+         "placeholder": "Name"
+       }
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "NotEmpty"
+       }
+     ]
+   }
+
+Delete the property ``properties.fluidAdditionalAttributes.placeholder``:
+
+.. code-block:: javascript
+
+   // value = 'Name'
+   var value = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').unset('properties.fluidAdditionalAttributes.placeholder');
+
+Example of the ``FormElement model`` after the ``unset()`` operation:
+
+.. code-block:: javascript
+
+   {
+     "identifier": "name",
+     "defaultValue": "",
+     "label": "Name",
+     "type": "Text",
+     "properties": {
+       "fluidAdditionalAttributes": {}
+     },
+     "__parentRenderable": "example-form/page-1 (filtered)",
+     "__identifierPath": "example-form/page-1/name",
+     "validators": [
+       {
+         "identifier": "NotEmpty"
+       }
+     ]
+   }
+
+Two exceptions are the two arrays of "finishers" / "validators" (``property
+collections``) and the ``renderables``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-propertycollectionproperties:
+
+Remove property collection properties
+'''''''''''''''''''''''''''''''''''''
+
+In principle, the same applies here as for :ref:`get property collection properties<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties>`.
+
+Delete the property ``options.minimum`` of the validator ``StringLength``:
+
+.. code-block:: javascript
+
+   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
+   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
+   formElement.unset(propertyPath);
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-renderables:
+
+Remove renderables
+''''''''''''''''''
+
+To delete a ``FormElement model``, the corresponding API method
+``getFormEditorApp().removeFormElement()`` should be used.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-on:
+
+Method: on()
+++++++++++++
+
+Any number of :ref:`Publisher/Subscriber<concepts-formeditor-basicjavascriptconcepts-events>`
+events can be assigned to any property path of a ``FormElement model``. Each
+``set()`` operation on this property path will then call these events. By
+default, EXT:form registers the event :ref:`core/formElement/somePropertyChanged<apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged>`
+for each property path.
+
+Example:
+
+.. code-block:: javascript
+
+   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').on('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
+   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
+   // now, the event 'my/custom/event' will be published
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-off:
+
+Method: off()
++++++++++++++
+
+Any event registered via :ref:`on()<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-on>`
+can be removed with off().
+
+Example:
+
+.. code-block:: javascript
+
+   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').off('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-getobjectdata:
+
+Method: getObjectData()
++++++++++++++++++++++++
+
+All ``FormElement model`` properties are private and cannot be manipulated
+directly from the outside. They can only be accessed via ``set()`` or
+``get()``. This method is used internally to obtain all data of a ``FormElement
+model`` in object form so that they can be used in, for example, Ajax requests.
+``getObjectData()`` returns a dereferenced object of the ``FormElement model``
+with all internal data, thus allowing read access to all data set via
+``set()``.
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-tostring:
+
+Method: toString()
+++++++++++++++++++
+
+A method that was implemented for debugging purposes. Returns the object data
+supplied by ``getObjectData()`` in string form.
+
+.. code-block:: javascript
+
+   console.log(formElement.toString());
+
+
+.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-clone:
+
+Method: clone()
++++++++++++++++
+
+If necessary, a form element can be cloned. Returns a dereferenced clone of the
+original ``FormElement model``.
+
+
+.. code-block:: javascript
+
+   var dolly = formElement.clone();
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/getRootForm.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/getRootForm.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/getRootForm.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/getRootForm.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setIdentifier.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setIdentifier.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setIdentifier.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setIdentifier.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setLabel.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setLabel.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setLabel.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setLabel.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setOptions.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setOptions.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractRenderable/setOptions.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractRenderable/setOptions.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/addElement.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/addElement.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/addElement.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/addElement.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/getElements.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/getElements.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/getElements.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/getElements.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/getElementsRecursively.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/getElementsRecursively.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/getElementsRecursively.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/getElementsRecursively.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/moveElementAfter.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/moveElementAfter.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/moveElementAfter.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/moveElementAfter.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/moveElementBefore.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/moveElementBefore.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/moveElementBefore.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/moveElementBefore.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/removeElement.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/removeElement.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/AbstractSection/removeElement.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/AbstractSection/removeElement.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/addValidator.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/addValidator.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/addValidator.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/addValidator.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/createValidator.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/createValidator.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/createValidator.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/createValidator.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getDefaultValue.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getDefaultValue.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getDefaultValue.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getDefaultValue.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getProperties.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getProperties.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getProperties.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getProperties.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getUniqueIdentifier.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getUniqueIdentifier.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/getUniqueIdentifier.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/getUniqueIdentifier.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/initializeFormElement.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/initializeFormElement.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/initializeFormElement.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/initializeFormElement.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/isRequired.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/isRequired.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/isRequired.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/isRequired.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setDataType.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setDataType.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setDataType.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setDataType.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setDefaultValue.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setDefaultValue.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setDefaultValue.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setDefaultValue.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setProperty.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setProperty.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setProperty.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setProperty.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setRenderingOption.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setRenderingOption.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/FormElementInterface/setRenderingOption.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/FormElementInterface/setRenderingOption.rst
diff --git a/typo3/sysext/form/Documentation/D/FrontendRendering/Index.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/Index.rst
new file mode 100644
index 000000000000..13638f8738e1
--- /dev/null
+++ b/typo3/sysext/form/Documentation/D/FrontendRendering/Index.rst
@@ -0,0 +1,1668 @@
+.. include:: /Includes.rst.txt
+
+
+.. _apireference-frontendrendering:
+
+Frontend rendering
+==================
+
+
+.. _apireference-frontendrendering-fluidformrenderer:
+
+TYPO3\\CMS\\Form\\Domain\\Renderer\\FluidFormRenderer
+-----------------------------------------------------
+
+
+.. _apireference-frontendrendering-fluidformrenderer-options:
+
+Options
+^^^^^^^
+
+The ``FluidFormRenderer`` uses some rendering options which are of particular importance,
+as they determine how the form field is resolved to a path in the file system.
+
+All rendering options are retrieved from the ``FormDefinition``, using the ``TYPO3\CMS\Form\Domain\Model\FormDefinition::getRenderingOptions()`` method.
+
+
+.. _apireference-frontendrendering-fluidformrenderer-options-templaterootpaths:
+
+templateRootPaths
++++++++++++++++++
+
+Used to define several paths for templates, which will be tried in reversed order (the paths are searched from bottom to top).
+The first folder where the desired template is found, is used. If the array keys are numeric, they are first sorted and then tried in reversed order.
+Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
+
+For example:
+
+templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Templates/
+$renderable->getType() == 'Form'
+Expected template file: EXT:form/Resources/Private/Frontend/Templates/Form.html
+
+Only the root element (``FormDefinition``) has to be a template file. All child form elements are partials. By default, the root element is called ``Form``.
+
+.. code-block:: yaml
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formElementsDefinition:
+               Form:
+                 renderingOptions:
+                   templateRootPaths:
+                     10: 'EXT:form/Resources/Private/Frontend/Templates/'
+
+
+.. _apireference-frontendrendering-fluidformrenderer-options-layoutrootpaths:
+
+layoutRootPaths
++++++++++++++++
+
+Used to define several paths for layouts, which will be tried in reversed order (the paths are searched from bottom to top).
+The first folder where the desired layout is found, is used. If the array keys are numeric, they are first sorted and then tried in reversed order.
+
+.. code-block:: yaml
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formElementsDefinition:
+               Form:
+                 renderingOptions:
+                   layoutRootPaths:
+                     10: 'EXT:form/Resources/Private/Frontend/Layouts/'
+
+
+.. _apireference-frontendrendering-fluidformrenderer-options-partialrootpaths:
+
+partialRootPaths
+++++++++++++++++
+
+Used to define several paths for partials, which will be tried in reversed order. The first folder where the desired partial is found, is used.
+The keys of the array define the order.
+
+Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
+
+For example:
+
+templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
+$renderable->getType() == 'Text'
+Expected template file: EXT:form/Resources/Private/Frontend/Partials/Text.html
+
+There is a setting available to set a custom partial name. Please read the section :ref:`templateName<apireference-frontendrendering-fluidformrenderer-options-templatename>`.
+
+.. code-block:: yaml
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formElementsDefinition:
+               Form:
+                 renderingOptions:
+                   partialRootPaths:
+                     10: 'EXT:form/Resources/Private/Frontend/Partials/'
+
+
+.. _apireference-frontendrendering-fluidformrenderer-options-templatename:
+
+templateName
+++++++++++++
+
+By default, the renderable type will be taken as the name for the partial.
+
+For example:
+
+partialRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
+$renderable->getType() == 'Text'
+Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
+
+Set ``templateName`` to define a custom name which should be used instead.
+
+For example:
+
+$renderable->getTemplateName() == 'Text'
+$renderable->getType() = Foo
+Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
+
+.. code-block:: yaml
+
+   TYPO3:
+     CMS:
+       Form:
+         prototypes:
+           standard:
+             formElementsDefinition:
+               Foo:
+                 renderingOptions:
+                   templateName: 'Text'
+
+
+.. _apireference-frontendrendering-renderviewHelper:
+
+"render" viewHelper
+-------------------
+
+.. _apireference-frontendrendering-renderviewHelper-arguments:
+
+Arguments
+^^^^^^^^^
+
+.. _apireference-frontendrendering-renderviewHelper-factoryclass:
+
+factoryClass
+++++++++++++
+
+A class name of a ``FormFactory``.
+This factory is used to create the ``TYPO3\CMS\Form\Domain\Model\FormDefinition`` which is the ``form definition`` Domain Model.
+If no ``factoryClass`` argument is passed, the factory supplied by EXT:form ``TYPO3\CMS\Form\ Domain\Factory\ArrayFormFactory`` is used.
+Another factory class is required if the form is to be generated programmatically.
+To do this you must implement your own ``FormFactory`` in which your own form is generated programmatically and passes this class name to the ViewHelper.
+This then renders the form.
+
+.. code-block:: html
+
+   <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
+
+
+.. _apireference-frontendrendering-renderviewHelper-persistenceidentifier:
+
+persistenceIdentifier
++++++++++++++++++++++
+
+The ``form definition`` to be found under ``persistenceIdentifier``.
+The PersistenceManager now loads the ``form definition`` which is found under ``persistenceIdentifier`` and passes this configuration to the ``factoryClass``.
+In this case, the ``factoryClass`` will be given an empty configuration array (if ``overrideConfiguration`` is not specified).
+
+.. code-block:: html
+
+   <formvh:render persistenceIdentifier="EXT:my_site_package/Resources/Private/Forms/SimpleContactForm.yaml" />
+
+
+.. _apireference-frontendrendering-renderviewHelper-overrideconfiguration:
+
+overrideConfiguration
++++++++++++++++++++++
+
+A configuration to be superimposed can be entered here.
+If a ``persistenceIdentifier`` is specified, the ``form definition`` which is found under ``persistenceIdentifier`` is loaded.
+This configuration is then superimposed with ``overrideConfiguration``. This configuration is then passed to the ``factoryClass``.
+If no ``persistenceIdentifier`` is specified, ``overrideConfiguration`` is passed directly to the ``factoryClass``.
+This way a configuration can be given to a ``factoryClass`` implementation.
+
+
+.. _apireference-frontendrendering-renderviewHelper-prototypename:
+
+prototypeName
++++++++++++++
+
+The name of the prototype, on which basis the ``factoryClass`` should create the form.
+If nothing is specified, the configuration (``form definition`` or ``overrideConfiguration``) is searched for the prototype's name.
+If no specification exists, the standard prototype ``standard`` is used.
+
+
+
+.. _apireference-frontendrendering-programmatically:
+
+Build forms programmatically
+----------------------------
+
+Implement a ``FormFactory`` and build the form::
+
+   declare(strict_types = 1);
+   namespace VENDOR\MySitePackage\Domain\Factory;
+
+   use TYPO3\CMS\Core\Utility\GeneralUtility;
+   use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
+   use TYPO3\CMS\Extbase\Validation\Validator\StringLengthValidator;
+   use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
+   use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
+   use TYPO3\CMS\Form\Domain\Model\FormDefinition;
+
+   class CustomFormFactory extends AbstractFormFactory
+   {
+
+       /**
+        * Build a FormDefinition.
+        * This example build a FormDefinition manually,
+        * so $configuration and $prototypeName are unused.
+        *
+        * @param array $configuration
+        * @param string $prototypeName
+        * @return FormDefinition
+        */
+       public function build(array $configuration, string $prototypeName = null): FormDefinition
+       {
+           $prototypeName = 'standard';
+           $configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
+           $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
+
+           $form = GeneralUtility::makeInstance(FormDefinition::class, 'MyCustomForm', $prototypeConfiguration);
+           $form->setRenderingOption('controllerAction', 'index');
+
+           $page1 = $form->createPage('page1');
+           $name = $page1->createElement('name', 'Text');
+           $name->setLabel('Name');
+           $name->addValidator(GeneralUtility::makeInstance(NotEmptyValidator::class));
+
+           $page2 = $form->createPage('page2');
+           $message = $page2->createElement('message', 'Textarea');
+           $message->setLabel('Message');
+           $message->addValidator(GeneralUtility::makeInstance(StringLengthValidator::class, ['minimum' => 5, 'maximum' => 20]));
+
+           // Creating a RadioButton/MultiCheckbox
+           $page3 = $form->createPage('page3');
+           $radio = $page3->createElement('checkbox', 'RadioButton');
+           $radio->setProperty('options', ['value1' => 'Label1', 'value2' => 'Label2']);
+           $radio->setLabel('My Radio ...');
+
+           $form->createFinisher('EmailToSender', [
+               'subject' => 'Hello',
+               'recipientAddress' => 'foo@example.com',
+               'senderAddress' => 'bar@example.com',
+           ]);
+
+           $this->triggerFormBuildingFinished($form);
+           return $form;
+       }
+   }
+
+Use this form within your fluid template.
+
+.. code-block:: html
+
+   <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods:
+
+Common API Methods
+^^^^^^^^^^^^^^^^^^
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-createpage:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createPage()
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Create a page with the given $identifier and attach this page to the form.
+
+- Create Page object based on the given $typeName
+- set defaults inside the Page object
+- attach Page object to this form
+- return the newly created Page object
+
+Signature::
+
+   public function createPage(string $identifier, string $typeName = 'Page'): Page;
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-createfinisher:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createFinisher()
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Create a finisher with the given $identifier and given $options and attach this finisher to the form.
+
+Signature::
+
+   public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-page-createelement:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page::createElement()
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Create a form element with the given $identifier and attach it to the page.
+
+- Create Form Element object based on the given $typeName
+- set defaults inside the Form Element (based on the parent form's field defaults)
+- attach Form Element to the Page
+- return the newly created Form Element object
+
+Signature::
+
+   public function createElement(string $identifier, string $typeName): FormElementInterface;
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-section-createelement:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section::createElement()
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Create a form element with the given $identifier and attach it to the section.
+
+- Create Form Element object based on the given $typeName
+- set defaults inside the Form Element (based on the parent form's field defaults)
+- attach Form Element to the Section
+- return the newly created Form Element object
+
+Signature::
+
+   public function createElement(string $identifier, string $typeName): FormElementInterface;
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-abstractrenderable-createvalidator:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\Renderable\\AbstractFormElement::createValidator()
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Create a validator for the element.
+Mainly possible for
+
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
+
+Signature::
+
+   public function createValidator(string $validatorIdentifier, array $options = []);
+
+
+.. _apireference-frontendrendering-programmatically-commonapimethods-initializeformelement:
+
+initializeFormElement()
++++++++++++++++++++++++
+
+Will be called as soon as the element is added to a form.
+Possible for
+
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
+
+Signature::
+
+   public function initializeFormElement();
+
+
+You can use this method to prefill form element data for example from database tables.
+All the classes you can see above extends from the ``TYPO3\CMS\Form\Domain\Model\FormElement\AbstractFormElement``.
+``AbstractFormElement`` implements this method like this::
+
+   public function initializeFormElement()
+   {
+       if (
+           isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
+           && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
+       ) {
+           foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'] as $className) {
+               $hookObj = GeneralUtility::makeInstance($className);
+               if (method_exists($hookObj, 'initializeFormElement')) {
+                   $hookObj->initializeFormElement(
+                       $this
+                   );
+               }
+           }
+       }
+   }
+
+If you extend you custom implementation from ``AbstractFormElement`` (and you should do this),
+it enables you to override the 'initializeFormElement' method within your custom implementation class.
+If you do not call the parents 'initializeFormElement' then no hook will be thrown.
+
+If your use case for a custom form element implementation means that you only want to initialize you form element
+programmatically (e.g to get databasedata) and no other special things are to do, you might prefer the hook.
+You only need a class which connects to this hook. Then detect the form element you wish to initialize.
+
+
+.. _apireference-frontendrendering-programmatically-apimethods:
+
+Further API Methods
+^^^^^^^^^^^^^^^^^^^
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormRuntime
+++++++++++++++++++++++++++++++++++++++++++++
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-overridecurrentpage:
+
+overrideCurrentPage()
+'''''''''''''''''''''
+
+Override the current page taken from the request, rendering the page with index $pageIndex instead.
+This is typically not needed in production code.
+You might prefer the hook :ref:`afterInitializeCurrentPage <apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage>`
+
+Signature::
+
+   public function overrideCurrentPage(int $pageIndex);
+
+Example::
+
+   $form = $formDefinition->bind($this->request);
+   $form->overrideCurrentPage($pageIndex);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-render:
+
+render()
+''''''''
+
+Render the form.
+
+Signature::
+
+   public function render();
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getidentifier:
+.. include:: RootRenderableInterface/getIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrequest:
+
+getRequest()
+''''''''''''
+
+Get the request this object is bound to.
+This is mostly relevant inside Finishers, where you f.e. want to redirect the user to another page.
+
+Signature::
+
+   public function getRequest(): Request;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getresponse:
+
+getResponse()
+'''''''''''''
+
+Get the response this object is bound to.
+This is mostly relevant inside Finishers, where you f.e. want to set response headers or output content.
+
+Signature::
+
+   public function getResponse(): Response;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getcurrentpage:
+
+getCurrentPage()
+''''''''''''''''
+
+Returns the currently selected page.
+
+Signature::
+
+   public function getCurrentPage(): Page;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpreviouspage:
+
+getPreviousPage()
+'''''''''''''''''
+
+Returns the previous page of the currently selected one or NULL if there is no previous page.
+
+Signature::
+
+   public function getPreviousPage();
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getnextpage:
+
+getNextPage()
+'''''''''''''
+
+Returns the next page of the currently selected one or NULL if there is no next page.
+
+Signature::
+
+   public function getNextPage();
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettype:
+.. include:: RootRenderableInterface/getType.rst
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getelementvalue:
+
+getElementValue()
+'''''''''''''''''
+
+Returns the value of the specified element.
+
+Signature::
+
+   public function getElementValue(string $identifier);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpages:
+
+getPages()
+''''''''''
+
+Return the form's pages in the correct order.
+
+Signature::
+
+   public function getPages(): array;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrenderingoptions:
+.. include:: RootRenderableInterface/getRenderingOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrendererclassname:
+.. include:: RootRenderableInterface/getRendererClassName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getlabel:
+.. include:: RootRenderableInterface/getLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettemplatename:
+.. include:: RenderableInterface/getTemplateName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getformdefinition:
+
+getFormDefinition()
+'''''''''''''''''''
+
+Get the underlying form definition from the runtime.
+
+Signature::
+
+   public function getFormDefinition(): FormDefinition;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition
++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addpage:
+
+addPage()
+'''''''''
+
+Add a new page at the end of the form.
+Instead of this method, you should use ``createPage`` instead.
+
+Signature::
+
+   public function addPage(Page $page);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createpage:
+
+createPage()
+''''''''''''
+
+Create a page with the given $identifier and attach this page to the form.
+
+- Create Page object based on the given $typeName
+- set defaults inside the Page object
+- attach Page object to this form
+- return the newly created Page object
+
+Signature::
+
+   public function createPage(string $identifier, string $typeName = 'Page'): Page;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpages:
+
+getPages()
+''''''''''
+
+Return the form's pages in the correct order.
+
+Signature::
+
+   public function getPages(): array;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-haspagewithindex:
+
+hasPageWithIndex()
+''''''''''''''''''
+
+Check whether a page with the given $index exists.
+
+Signature::
+
+   public function hasPageWithIndex(int $index): bool;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpagebyindex:
+
+getPageByIndex()
+''''''''''''''''
+
+Get the page with the passed index. The first page has index zero.
+If page at $index does not exist, an exception is thrown.
+
+Signature::
+
+   public function getPageByIndex(int $index);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addfinisher:
+
+addFinisher()
+'''''''''''''
+
+Adds the specified finisher to the form.
+Instead of this method, you should use ``createFinisher`` instead.
+
+Signature::
+
+   public function addFinisher(FinisherInterface $finisher);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createfinisher:
+
+createFinisher()
+''''''''''''''''
+
+Create a finisher with the given $identifier and given $options and attach this finisher to the form.
+
+Signature::
+
+   public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getfinishers:
+
+getFinishers()
+''''''''''''''
+
+Gets all finishers of the form.
+
+Signature::
+
+   public function getFinishers(): array;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getelementbyidentifier:
+
+getElementByIdentifier()
+''''''''''''''''''''''''
+
+Get a form element by its identifier.
+If identifier does not exist, returns NULL.
+
+Signature::
+
+   public function getElementByIdentifier(string $elementIdentifier);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-movepageafter:
+
+movePageAfter()
+'''''''''''''''
+
+Move $pageToMove after $referencePage.
+
+Signature::
+
+   public function movePageAfter(Page $pageToMove, Page $referencePage);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-removepage:
+
+removePage()
+''''''''''''
+
+Remove $pageToRemove from the form.
+
+Signature::
+
+   public function removePage(Page $pageToRemove);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-bind:
+
+bind()
+''''''
+
+Bind the current request and response to this form instance, effectively creating a new "instance" of the Form.
+
+Signature::
+
+   public function bind(Request $request): FormRuntime;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getprocessingrule:
+
+getProcessingRule()
+'''''''''''''''''''
+
+Get the processing rule which contains information for property mappings and validations.
+
+Signature::
+
+   public function getProcessingRule(string $propertyPath): ProcessingRule;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettype:
+.. include:: RootRenderableInterface/getType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getidentifier:
+.. include:: RootRenderableInterface/getIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setidentifier:
+.. include:: AbstractRenderable/setIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setoptions:
+.. include:: AbstractRenderable/setOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addvalidator:
+.. include:: FormElementInterface/addValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setdatatype:
+.. include:: FormElementInterface/setDataType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrendererclassname:
+.. include:: RootRenderableInterface/getRendererClassName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrendererclassname:
+
+setRendererClassName()
+''''''''''''''''''''''
+
+Set the renderer class name.
+
+Signature::
+
+   public function setRendererClassName(string $rendererClassName);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrenderingoptions:
+.. include:: RootRenderableInterface/getRenderingOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrenderingoption:
+.. include:: FormElementInterface/setRenderingOption.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getparentrenderable:
+.. include:: RenderableInterface/getParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setparentrenderable:
+.. include:: RenderableInterface/setParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrootform:
+.. include:: AbstractRenderable/getRootForm.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getlabel:
+.. include:: RootRenderableInterface/getLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setlabel:
+.. include:: AbstractRenderable/setLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettemplatename:
+.. include:: RenderableInterface/getTemplateName.rst
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-page:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page
++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getelements:
+.. include:: AbstractSection/getElements.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getelementsrecursively:
+.. include:: AbstractSection/getElementsRecursively.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-addelement:
+.. include:: AbstractSection/addElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-createelement:
+
+createElement()
+'''''''''''''''
+
+Create a form element with the given $identifier and attach it to the page.
+
+- Create Form Element object based on the given $typeName
+- set defaults inside the Form Element (based on the parent form's field defaults)
+- attach Form Element to the Page
+- return the newly created Form Element object
+
+Signature::
+
+   public function createElement(string $identifier, string $typeName): FormElementInterface;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-moveelementbefore:
+.. include:: AbstractSection/moveElementBefore.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-moveelementafter:
+.. include:: AbstractSection/moveElementAfter.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-removeelement:
+.. include:: AbstractSection/removeElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-gettype:
+.. include:: RootRenderableInterface/getType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getidentifier:
+.. include:: RootRenderableInterface/getIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setidentifier:
+.. include:: AbstractRenderable/setIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setoptions:
+.. include:: AbstractRenderable/setOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-addvalidator:
+.. include:: FormElementInterface/addValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-createvalidator:
+.. include:: FormElementInterface/createValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setdatatype:
+.. include:: FormElementInterface/setDataType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getrendererclassname:
+.. include:: RootRenderableInterface/getRendererClassName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getrenderingoptions:
+.. include:: RootRenderableInterface/getRenderingOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setrenderingoption:
+.. include:: FormElementInterface/setRenderingOption.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getparentrenderable:
+.. include:: RenderableInterface/getParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setparentrenderable:
+.. include:: RenderableInterface/setParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getrootform:
+.. include:: AbstractRenderable/getRootForm.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-getlabel:
+.. include:: RootRenderableInterface/getLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-setlabel:
+.. include:: AbstractRenderable/setLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-page-gettemplatename:
+.. include:: RenderableInterface/getTemplateName.rst
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-section:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-initializeformelement:
+.. include:: FormElementInterface/initializeFormElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getuniqueidentifier:
+.. include:: FormElementInterface/getUniqueIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setproperty:
+.. include:: FormElementInterface/setProperty.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getproperties:
+.. include:: FormElementInterface/getProperties.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-isrequired:
+.. include:: FormElementInterface/isRequired.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getelements:
+.. include:: AbstractSection/getElements.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getelementsrecursively:
+.. include:: AbstractSection/getElementsRecursively.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-addelement:
+.. include:: AbstractSection/addElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-createelement:
+
+createElement()
+'''''''''''''''
+
+Create a form element with the given $identifier and attach it to the section.
+
+- Create Form Element object based on the given $typeName
+- set defaults inside the Form Element (based on the parent form's field defaults)
+- attach Form Element to the Section
+- return the newly created Form Element object
+
+Signature::
+
+   public function createElement(string $identifier, string $typeName): FormElementInterface;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-moveelementbefore:
+.. include:: AbstractSection/moveElementBefore.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-moveelementafter:
+.. include:: AbstractSection/moveElementAfter.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-removeelement:
+.. include:: AbstractSection/removeElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-gettype:
+.. include:: RootRenderableInterface/getType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getidentifier:
+.. include:: RootRenderableInterface/getIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setidentifier:
+.. include:: AbstractRenderable/setIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setoptions:
+.. include:: AbstractRenderable/setOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-addvalidator:
+.. include:: FormElementInterface/addValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-createvalidator:
+.. include:: FormElementInterface/createValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setdatatype:
+.. include:: FormElementInterface/setDataType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getrendererclassname:
+.. include:: RootRenderableInterface/getRendererClassName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getrenderingoptions:
+.. include:: RootRenderableInterface/getRenderingOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setrenderingoption:
+.. include:: FormElementInterface/setRenderingOption.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getparentrenderable:
+.. include:: RenderableInterface/getParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setparentrenderable:
+.. include:: RenderableInterface/setParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getrootform:
+.. include:: AbstractRenderable/getRootForm.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-getlabel:
+.. include:: RootRenderableInterface/getLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-setlabel:
+.. include:: AbstractRenderable/setLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-section-gettemplatename:
+.. include:: RenderableInterface/getTemplateName.rst
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement:
+
+TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AbstractFormElement
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The following classes extends from ``AbstractFormElement`` and therefore contain the following API methods.
+
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
+- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-initializeformelement:
+.. include:: FormElementInterface/initializeFormElement.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getuniqueidentifier:
+.. include:: FormElementInterface/getUniqueIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getdefaultvalue:
+.. include:: FormElementInterface/getDefaultValue.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdefaultvalue:
+.. include:: FormElementInterface/setDefaultValue.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setproperty:
+.. include:: FormElementInterface/setProperty.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getproperties:
+.. include:: FormElementInterface/getProperties.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-isrequired:
+.. include:: FormElementInterface/isRequired.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettype:
+.. include:: RootRenderableInterface/getType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getidentifier:
+.. include:: RootRenderableInterface/getIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setidentifier:
+.. include:: AbstractRenderable/setIdentifier.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setoptions:
+.. include:: AbstractRenderable/setOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-addvalidator:
+.. include:: FormElementInterface/addValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-createvalidator:
+.. include:: FormElementInterface/createValidator.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdatatype:
+.. include:: FormElementInterface/setDataType.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrendererclassname:
+.. include:: RootRenderableInterface/getRendererClassName.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrenderingoptions:
+.. include:: RootRenderableInterface/getRenderingOptions.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setrenderingoption:
+.. include:: FormElementInterface/setRenderingOption.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getparentrenderable:
+.. include:: RenderableInterface/getParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setparentrenderable:
+.. include:: RenderableInterface/setParentRenderable.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrootform:
+.. include:: AbstractRenderable/getRootForm.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getlabel:
+.. include:: RootRenderableInterface/getLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setlabel:
+.. include:: AbstractRenderable/setLabel.rst
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettemplatename:
+.. include:: RenderableInterface/getTemplateName.rst
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher:
+
+TYPO3\\CMS\\Form\\Domain\\Finishers\\AbstractFinisher
++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+The following classes extends from ``AbstractFinisher`` and therefore contain the following API methods.
+
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\ClosureFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\ConfirmationFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\DeleteUploadsFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\EmailFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\FlashMessageFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\RedirectFinisher
+- TYPO3\\CMS\\Form\\Domain\\Finishers\\SaveToDatabaseFinisher
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-execute:
+
+execute()
+'''''''''
+
+Executes the finisher. ``AbstractFinisher::execute()`` call ``$this->executeInternal()`` at the end. Own finisher
+implementations which extends from  ``AbstractFinisher:`` must start their own logic within ``executeInternal()``.
+
+Signature::
+
+   public function execute(FinisherContext $finisherContext);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoptions:
+
+setOptions()
+''''''''''''
+
+Set the finisher options. Instead of directly accessing them, you should rather use ``parseOption()``.
+
+Signature::
+
+   public function setOptions(array $options);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoption:
+
+setOption()
+'''''''''''
+
+Sets a single finisher option.
+
+Signature::
+
+   public function setOption(string $optionName, $optionValue);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-parseoption:
+
+parseOption()
+'''''''''''''
+
+Please read :ref:`Accessing finisher options<concepts-finishers-customfinisherimplementations-accessingoptions>`
+
+Signature::
+
+   protected function parseOption(string $optionName);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishercontext:
+
+TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherContext
+++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-cancel:
+
+cancel()
+''''''''
+
+Cancels the finisher invocation after the current finisher.
+
+Signature::
+
+   public function cancel();
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformruntime:
+
+getFormRuntime()
+''''''''''''''''
+
+The Form Runtime that is associated with the current finisher.
+
+Signature::
+
+   public function getFormRuntime(): FormRuntime;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformvalues:
+
+getFormValues()
+'''''''''''''''
+
+The values of the submitted form (after validation and property mapping).
+
+Signature::
+
+   public function getFormValues(): array;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getfinishervariableprovider:
+
+getFinisherVariableProvider()
+'''''''''''''''''''''''''''''
+
+Returns the current FinisherVariableProvider.
+
+Signature::
+
+   public function getFinisherVariableProvider(): FinisherVariableProvider;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider:
+
+TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherVariableProvider
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+Please read :ref:`Share data between finishers<concepts-finishers-customfinisherimplementations-finishercontext-sharedatabetweenfinishers>`
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-add:
+
+add()
+'''''
+
+Add a variable to the finisher variable provider.
+In case the value is already inside, it is silently overridden.
+
+Signature::
+
+   public function add(string $finisherIdentifier, string $key, $value);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-get:
+
+get()
+'''''
+
+Gets a variable from the finisher variable provider.
+
+Signature::
+
+   public function get(string $finisherIdentifier, string $key, $default = null);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-exists:
+
+exists()
+''''''''
+
+Determine whether there is a variable stored for the given key.
+
+Signature::
+
+   public function exists($finisherIdentifier, $key): bool;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-remove:
+
+remove()
+''''''''
+
+Remove a value from the finisher variable provider.
+
+Signature::
+
+   public function remove(string $finisherIdentifier, string $key);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-configurationservice:
+
+TYPO3\\CMS\\Form\\Domain\\Configuration\\ConfigurationService
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-configurationservice-getprototypeconfiguration:
+
+getPrototypeConfiguration()
+'''''''''''''''''''''''''''
+
+Get the configuration for a given $prototypeName
+
+Signature::
+
+   public function getPrototypeConfiguration(string $prototypeName): array;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory:
+
+TYPO3\\CMS\\Form\\Domain\\Factory\\AbstractFormFactory
+++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory-triggerformbuildingfinished:
+
+triggerFormBuildingFinished()
+'''''''''''''''''''''''''''''
+
+Helper to be called by every ``FormFactory`` which extends from ``AbstractFormFactory`` after
+everything has been built to call the "afterBuildingFinished" hook on all form elements.
+
+Signature::
+
+   protected function triggerFormBuildingFinished(FormDefinition $form);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface:
+
+TYPO3\\CMS\\Form\\Domain\\Factory\\FormFactoryInterface
++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface-build:
+
+build()
+'''''''
+
+Build a form definition, depending on some configuration.
+
+Signature::
+
+   public function build(array $configuration, string $prototypeName = null): FormDefinition;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface:
+
+TYPO3\\CMS\\Form\\Domain\\Renderer\\RendererInterface
++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-render:
+
+render()
+''''''''
+
+Renders the FormDefinition. This method is expected to call the ``beforeRendering`` hook on each form element::
+
+   public function render(): string;
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setformruntime:
+
+setFormRuntime()
+''''''''''''''''
+
+Set the current ``FormRuntime``::
+
+   public function setFormRuntime(FormRuntime $formRuntime);
+
+
+.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-getformruntime:
+
+getFormRuntime()
+''''''''''''''''
+
+Get the current ``FormRuntime``::
+
+   public function getFormRuntime(): FormRuntime;
+
+
+.. _apireference-frontendrendering-runtimemanipulation:
+
+Runtime manipulation
+--------------------
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks:
+
+Hooks
+^^^^^
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement:
+
+initializeFormElement
++++++++++++++++++++++
+
+You can connect to this hook and initialize a form element without defining a
+custom implementaion to access the element's ``initializeFormElement`` method.
+You only need a class which connects to this hook. Then detect the form
+element you wish to initialize. For example, you can use this hook to prefill
+form element data from database tables. Note that this hook will be called
+**after** all properties from the prototype configuration are set in the form
+element but **before** the properties from the form definition are set in the
+form element. If you want to prefill form element data after the complete
+form element is configured you should use the
+:ref:`afterBuildingFinished<apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished>` hook.
+
+The initializeFormElement hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::createElement()``
+and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::createElement()``.
+That means the hook will **not** be triggered for ``Pages``. At this point
+you do not have access to submitted form element values.
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
+    * @return void
+    */
+   public function initializeFormElement(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
+   {
+       if ($renderable->getUniqueIdentifier() === 'contactForm-text-1') {
+           $renderable->setDefaultValue('foo');
+       }
+   }
+
+
+.. _useATimestampAsKeyPlease:
+
+What does <useATimestampAsKeyPlease> mean?
+++++++++++++++++++++++++++++++++++++++++++
+
+Timestamps are recommended for hooks such as those of the form framework, as
+seen in the following example::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+Leaving the section ``<useATimestampAsKeyPlease>`` as is is not recommended.
+It does nothing except cause the extension to fail and an error message to be
+delivered. Nor should it be replaced with a function like time(), as the key
+should be unalterable. Instead, replace this section with the current UNIX
+timestamp the moment you are implementing the hook. Check out the following
+example::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][1507018413]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+The purpose of timestamps is to prevent conflicts that arise when two or more
+extensions within one TYPO3 installation use identical keys (e.g.
+``$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement']['foo'])``.
+When timestamps are used, even a one-second difference in the time different
+hooks were connected ensures that one hook does not override the other.
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable:
+
+beforeRemoveFromParentRenderable
+++++++++++++++++++++++++++++++++
+
+This hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormDefinition::removePage()``,  ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::removeElement()``
+and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::removeElement()``
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
+    * @return void
+    */
+   public function beforeRemoveFromParentRenderable(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
+   {
+   }
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished:
+
+afterBuildingFinished
++++++++++++++++++++++
+
+This hook is called for each form element after the class ``TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory``
+has built the entire form. This hook is triggered just before the
+``FormRuntime`` object is generated. At this point, no run-time information
+(e.g. assigned form values) is yet available. It can, for example, be used to
+generate new form elements within complex forms. The ``ArrayFormFactory`` is
+used by EXT:form via the ``RenderViewHelper`` to render forms using a ``form
+definition`` YAML file. Each form factory implementation must deal with the
+calling of this hook themselves. EXT:form itself uses this hook to initialize
+the property-mapper configuration for ``FileUpload`` elements.
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterBuildingFinished'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
+    * @return void
+    */
+   public function afterBuildingFinished(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
+   {
+   }
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage:
+
+afterInitializeCurrentPage
+++++++++++++++++++++++++++
+
+EXT:form automatically detects the page that should be shown and allow users
+only to jump to the directly following (or previous) pages. This hook enables
+you to implement a custom behavior, for example pages that are shown only when
+other form elements have specific values.
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterInitializeCurrentPage'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
+    * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage
+    * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage
+    * @param mixed $elementValue submitted value of the element *before post processing*
+    * @return null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
+    */
+   public function afterInitializeCurrentPage(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage = null, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage = null, array $requestArguments = []): ?\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
+   {
+       return $currentPage;
+   }
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit:
+
+afterSubmit
++++++++++++
+
+You can use it for example for dynamic validations which depends on other submitted form element values.
+This hook is invoked by the ``FormRuntime`` for each form element **before** values are property mapped, validated and pushed within the FormRuntime's ``FormState``.
+If the first page is submitted at the first time you cannot access the form element values from the first page by just calling ``$formRuntime['<someOtherFormElementIdentifier>']`` to access
+the submitted form element values from the first page. In this case you can access the submitted raw data through ``$requestArguments``.
+EXT:form itself uses this hook to dynamically add validation errors for ``AdvancedPassword`` form elements.
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterSubmit'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
+    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
+    * @param mixed $elementValue submitted value of the element *before post processing*
+    * @param array $requestArguments submitted raw request values
+    * @return void
+    */
+   public function afterSubmit(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable, $elementValue, array $requestArguments = [])
+   {
+       return $elementValue;
+   }
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering:
+
+beforeRendering
++++++++++++++++
+
+This is a hook that is invoked by the rendering system before the corresponding element is rendered.
+Use this to access previously submitted values and/or modify the ``FormRuntime`` before an element is outputted to the browser.
+This hook is called after all validations and property mappings are done.
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-connect:
+
+Connect to the hook
+'''''''''''''''''''
+
+::
+
+   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'][<useATimestampAsKeyPlease>]
+       = \VENDOR\YourNamespace\YourClass::class;
+
+
+.. note::
+
+   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
+   means?
+
+
+.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-use:
+
+Use the hook
+''''''''''''
+
+::
+
+   /**
+    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
+    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable
+    * @return void
+    */
+   public function beforeRendering(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable)
+   {
+   }
\ No newline at end of file
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/getParentRenderable.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/getParentRenderable.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/getParentRenderable.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/getParentRenderable.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/getTemplateName.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/getTemplateName.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/getTemplateName.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/getTemplateName.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/setParentRenderable.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/setParentRenderable.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RenderableInterface/setParentRenderable.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RenderableInterface/setParentRenderable.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getIdentifier.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getIdentifier.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getIdentifier.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getIdentifier.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getLabel.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getLabel.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getLabel.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getLabel.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getRendererClassName.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getRendererClassName.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getRendererClassName.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getRendererClassName.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getRenderingOptions.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getRenderingOptions.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getRenderingOptions.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getRenderingOptions.rst
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getType.rst b/typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getType.rst
similarity index 100%
rename from typo3/sysext/form/Documentation/I/ApiReference/RootRenderableInterface/getType.rst
rename to typo3/sysext/form/Documentation/D/FrontendRendering/RootRenderableInterface/getType.rst
diff --git a/typo3/sysext/form/Documentation/D/Index.rst b/typo3/sysext/form/Documentation/D/Index.rst
new file mode 100644
index 000000000000..854dc541b9f9
--- /dev/null
+++ b/typo3/sysext/form/Documentation/D/Index.rst
@@ -0,0 +1,18 @@
+.. include:: /Includes.rst.txt
+
+
+.. _apireference:
+
+=============================
+For Developers / API Reference
+=============================
+
+This chapter is a complete reference of the API of the form framework. It
+mainly addresses your concerns as a developer.
+
+.. toctree::
+   :maxdepth: 1
+
+   FinisherOptions/Index
+   FormEditor/Index
+   FrontendRendering/Index
diff --git a/typo3/sysext/form/Documentation/I/ApiReference/Index.rst b/typo3/sysext/form/Documentation/I/ApiReference/Index.rst
deleted file mode 100644
index d9585c69f140..000000000000
--- a/typo3/sysext/form/Documentation/I/ApiReference/Index.rst
+++ /dev/null
@@ -1,5533 +0,0 @@
-.. include:: /Includes.rst.txt
-
-
-.. _apireference:
-
-=============
-API Reference
-=============
-
-This chapter is a complete reference of the API of the form framework. It
-mainly addresses your concerns as a developer.
-
-
-.. _apireference-frontendrendering:
-
-Frontend rendering
-==================
-
-
-.. _apireference-frontendrendering-fluidformrenderer:
-
-TYPO3\\CMS\\Form\\Domain\\Renderer\\FluidFormRenderer
------------------------------------------------------
-
-
-.. _apireference-frontendrendering-fluidformrenderer-options:
-
-Options
-^^^^^^^
-
-The ``FluidFormRenderer`` uses some rendering options which are of particular importance,
-as they determine how the form field is resolved to a path in the file system.
-
-All rendering options are retrieved from the ``FormDefinition``, using the ``TYPO3\CMS\Form\Domain\Model\FormDefinition::getRenderingOptions()`` method.
-
-
-.. _apireference-frontendrendering-fluidformrenderer-options-templaterootpaths:
-
-templateRootPaths
-+++++++++++++++++
-
-Used to define several paths for templates, which will be tried in reversed order (the paths are searched from bottom to top).
-The first folder where the desired template is found, is used. If the array keys are numeric, they are first sorted and then tried in reversed order.
-Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
-
-For example:
-
-templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Templates/
-$renderable->getType() == 'Form'
-Expected template file: EXT:form/Resources/Private/Frontend/Templates/Form.html
-
-Only the root element (``FormDefinition``) has to be a template file. All child form elements are partials. By default, the root element is called ``Form``.
-
-.. code-block:: yaml
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formElementsDefinition:
-               Form:
-                 renderingOptions:
-                   templateRootPaths:
-                     10: 'EXT:form/Resources/Private/Frontend/Templates/'
-
-
-.. _apireference-frontendrendering-fluidformrenderer-options-layoutrootpaths:
-
-layoutRootPaths
-+++++++++++++++
-
-Used to define several paths for layouts, which will be tried in reversed order (the paths are searched from bottom to top).
-The first folder where the desired layout is found, is used. If the array keys are numeric, they are first sorted and then tried in reversed order.
-
-.. code-block:: yaml
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formElementsDefinition:
-               Form:
-                 renderingOptions:
-                   layoutRootPaths:
-                     10: 'EXT:form/Resources/Private/Frontend/Layouts/'
-
-
-.. _apireference-frontendrendering-fluidformrenderer-options-partialrootpaths:
-
-partialRootPaths
-++++++++++++++++
-
-Used to define several paths for partials, which will be tried in reversed order. The first folder where the desired partial is found, is used.
-The keys of the array define the order.
-
-Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
-
-For example:
-
-templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
-$renderable->getType() == 'Text'
-Expected template file: EXT:form/Resources/Private/Frontend/Partials/Text.html
-
-There is a setting available to set a custom partial name. Please read the section :ref:`templateName<apireference-frontendrendering-fluidformrenderer-options-templatename>`.
-
-.. code-block:: yaml
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formElementsDefinition:
-               Form:
-                 renderingOptions:
-                   partialRootPaths:
-                     10: 'EXT:form/Resources/Private/Frontend/Partials/'
-
-
-.. _apireference-frontendrendering-fluidformrenderer-options-templatename:
-
-templateName
-++++++++++++
-
-By default, the renderable type will be taken as the name for the partial.
-
-For example:
-
-partialRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
-$renderable->getType() == 'Text'
-Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
-
-Set ``templateName`` to define a custom name which should be used instead.
-
-For example:
-
-$renderable->getTemplateName() == 'Text'
-$renderable->getType() = Foo
-Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
-
-.. code-block:: yaml
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formElementsDefinition:
-               Foo:
-                 renderingOptions:
-                   templateName: 'Text'
-
-
-.. _apireference-frontendrendering-renderviewHelper:
-
-"render" viewHelper
--------------------
-
-.. _apireference-frontendrendering-renderviewHelper-arguments:
-
-Arguments
-^^^^^^^^^
-
-.. _apireference-frontendrendering-renderviewHelper-factoryclass:
-
-factoryClass
-++++++++++++
-
-A class name of a ``FormFactory``.
-This factory is used to create the ``TYPO3\CMS\Form\Domain\Model\FormDefinition`` which is the ``form definition`` Domain Model.
-If no ``factoryClass`` argument is passed, the factory supplied by EXT:form ``TYPO3\CMS\Form\ Domain\Factory\ArrayFormFactory`` is used.
-Another factory class is required if the form is to be generated programmatically.
-To do this you must implement your own ``FormFactory`` in which your own form is generated programmatically and passes this class name to the ViewHelper.
-This then renders the form.
-
-.. code-block:: html
-
-   <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
-
-
-.. _apireference-frontendrendering-renderviewHelper-persistenceidentifier:
-
-persistenceIdentifier
-+++++++++++++++++++++
-
-The ``form definition`` to be found under ``persistenceIdentifier``.
-The PersistenceManager now loads the ``form definition`` which is found under ``persistenceIdentifier`` and passes this configuration to the ``factoryClass``.
-In this case, the ``factoryClass`` will be given an empty configuration array (if ``overrideConfiguration`` is not specified).
-
-.. code-block:: html
-
-   <formvh:render persistenceIdentifier="EXT:my_site_package/Resources/Private/Forms/SimpleContactForm.yaml" />
-
-
-.. _apireference-frontendrendering-renderviewHelper-overrideconfiguration:
-
-overrideConfiguration
-+++++++++++++++++++++
-
-A configuration to be superimposed can be entered here.
-If a ``persistenceIdentifier`` is specified, the ``form definition`` which is found under ``persistenceIdentifier`` is loaded.
-This configuration is then superimposed with ``overrideConfiguration``. This configuration is then passed to the ``factoryClass``.
-If no ``persistenceIdentifier`` is specified, ``overrideConfiguration`` is passed directly to the ``factoryClass``.
-This way a configuration can be given to a ``factoryClass`` implementation.
-
-
-.. _apireference-frontendrendering-renderviewHelper-prototypename:
-
-prototypeName
-+++++++++++++
-
-The name of the prototype, on which basis the ``factoryClass`` should create the form.
-If nothing is specified, the configuration (``form definition`` or ``overrideConfiguration``) is searched for the prototype's name.
-If no specification exists, the standard prototype ``standard`` is used.
-
-
-
-.. _apireference-frontendrendering-programmatically:
-
-Build forms programmatically
-----------------------------
-
-Implement a ``FormFactory`` and build the form::
-
-   declare(strict_types = 1);
-   namespace VENDOR\MySitePackage\Domain\Factory;
-
-   use TYPO3\CMS\Core\Utility\GeneralUtility;
-   use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
-   use TYPO3\CMS\Extbase\Validation\Validator\StringLengthValidator;
-   use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
-   use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
-   use TYPO3\CMS\Form\Domain\Model\FormDefinition;
-
-   class CustomFormFactory extends AbstractFormFactory
-   {
-
-       /**
-        * Build a FormDefinition.
-        * This example build a FormDefinition manually,
-        * so $configuration and $prototypeName are unused.
-        *
-        * @param array $configuration
-        * @param string $prototypeName
-        * @return FormDefinition
-        */
-       public function build(array $configuration, string $prototypeName = null): FormDefinition
-       {
-           $prototypeName = 'standard';
-           $configurationService = GeneralUtility::makeInstance(ConfigurationService::class);
-           $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
-
-           $form = GeneralUtility::makeInstance(FormDefinition::class, 'MyCustomForm', $prototypeConfiguration);
-           $form->setRenderingOption('controllerAction', 'index');
-
-           $page1 = $form->createPage('page1');
-           $name = $page1->createElement('name', 'Text');
-           $name->setLabel('Name');
-           $name->addValidator(GeneralUtility::makeInstance(NotEmptyValidator::class));
-
-           $page2 = $form->createPage('page2');
-           $message = $page2->createElement('message', 'Textarea');
-           $message->setLabel('Message');
-           $message->addValidator(GeneralUtility::makeInstance(StringLengthValidator::class, ['minimum' => 5, 'maximum' => 20]));
-
-           // Creating a RadioButton/MultiCheckbox
-           $page3 = $form->createPage('page3');
-           $radio = $page3->createElement('checkbox', 'RadioButton');
-           $radio->setProperty('options', ['value1' => 'Label1', 'value2' => 'Label2']);
-           $radio->setLabel('My Radio ...');
-
-           $form->createFinisher('EmailToSender', [
-               'subject' => 'Hello',
-               'recipientAddress' => 'foo@example.com',
-               'senderAddress' => 'bar@example.com',
-           ]);
-
-           $this->triggerFormBuildingFinished($form);
-           return $form;
-       }
-   }
-
-Use this form within your fluid template.
-
-.. code-block:: html
-
-   <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods:
-
-Common API Methods
-^^^^^^^^^^^^^^^^^^
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-createpage:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createPage()
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Create a page with the given $identifier and attach this page to the form.
-
-- Create Page object based on the given $typeName
-- set defaults inside the Page object
-- attach Page object to this form
-- return the newly created Page object
-
-Signature::
-
-   public function createPage(string $identifier, string $typeName = 'Page'): Page;
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-createfinisher:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createFinisher()
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Create a finisher with the given $identifier and given $options and attach this finisher to the form.
-
-Signature::
-
-   public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-page-createelement:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page::createElement()
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Create a form element with the given $identifier and attach it to the page.
-
-- Create Form Element object based on the given $typeName
-- set defaults inside the Form Element (based on the parent form's field defaults)
-- attach Form Element to the Page
-- return the newly created Form Element object
-
-Signature::
-
-   public function createElement(string $identifier, string $typeName): FormElementInterface;
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-section-createelement:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section::createElement()
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Create a form element with the given $identifier and attach it to the section.
-
-- Create Form Element object based on the given $typeName
-- set defaults inside the Form Element (based on the parent form's field defaults)
-- attach Form Element to the Section
-- return the newly created Form Element object
-
-Signature::
-
-   public function createElement(string $identifier, string $typeName): FormElementInterface;
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-abstractrenderable-createvalidator:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\Renderable\\AbstractFormElement::createValidator()
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Create a validator for the element.
-Mainly possible for
-
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
-
-Signature::
-
-   public function createValidator(string $validatorIdentifier, array $options = []);
-
-
-.. _apireference-frontendrendering-programmatically-commonapimethods-initializeformelement:
-
-initializeFormElement()
-+++++++++++++++++++++++
-
-Will be called as soon as the element is added to a form.
-Possible for
-
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
-
-Signature::
-
-   public function initializeFormElement();
-
-
-You can use this method to prefill form element data for example from database tables.
-All the classes you can see above extends from the ``TYPO3\CMS\Form\Domain\Model\FormElement\AbstractFormElement``.
-``AbstractFormElement`` implements this method like this::
-
-   public function initializeFormElement()
-   {
-       if (
-           isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
-           && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
-       ) {
-           foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'] as $className) {
-               $hookObj = GeneralUtility::makeInstance($className);
-               if (method_exists($hookObj, 'initializeFormElement')) {
-                   $hookObj->initializeFormElement(
-                       $this
-                   );
-               }
-           }
-       }
-   }
-
-If you extend you custom implementation from ``AbstractFormElement`` (and you should do this),
-it enables you to override the 'initializeFormElement' method within your custom implementation class.
-If you do not call the parents 'initializeFormElement' then no hook will be thrown.
-
-If your use case for a custom form element implementation means that you only want to initialize you form element
-programmatically (e.g to get databasedata) and no other special things are to do, you might prefer the hook.
-You only need a class which connects to this hook. Then detect the form element you wish to initialize.
-
-
-.. _apireference-frontendrendering-programmatically-apimethods:
-
-Further API Methods
-^^^^^^^^^^^^^^^^^^^
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormRuntime
-++++++++++++++++++++++++++++++++++++++++++++
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-overridecurrentpage:
-
-overrideCurrentPage()
-'''''''''''''''''''''
-
-Override the current page taken from the request, rendering the page with index $pageIndex instead.
-This is typically not needed in production code.
-You might prefer the hook :ref:`afterInitializeCurrentPage <apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage>`
-
-Signature::
-
-   public function overrideCurrentPage(int $pageIndex);
-
-Example::
-
-   $form = $formDefinition->bind($this->request);
-   $form->overrideCurrentPage($pageIndex);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-render:
-
-render()
-''''''''
-
-Render the form.
-
-Signature::
-
-   public function render();
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getidentifier:
-.. include:: RootRenderableInterface/getIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrequest:
-
-getRequest()
-''''''''''''
-
-Get the request this object is bound to.
-This is mostly relevant inside Finishers, where you f.e. want to redirect the user to another page.
-
-Signature::
-
-   public function getRequest(): Request;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getresponse:
-
-getResponse()
-'''''''''''''
-
-Get the response this object is bound to.
-This is mostly relevant inside Finishers, where you f.e. want to set response headers or output content.
-
-Signature::
-
-   public function getResponse(): Response;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getcurrentpage:
-
-getCurrentPage()
-''''''''''''''''
-
-Returns the currently selected page.
-
-Signature::
-
-   public function getCurrentPage(): Page;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpreviouspage:
-
-getPreviousPage()
-'''''''''''''''''
-
-Returns the previous page of the currently selected one or NULL if there is no previous page.
-
-Signature::
-
-   public function getPreviousPage();
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getnextpage:
-
-getNextPage()
-'''''''''''''
-
-Returns the next page of the currently selected one or NULL if there is no next page.
-
-Signature::
-
-   public function getNextPage();
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettype:
-.. include:: RootRenderableInterface/getType.rst
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getelementvalue:
-
-getElementValue()
-'''''''''''''''''
-
-Returns the value of the specified element.
-
-Signature::
-
-   public function getElementValue(string $identifier);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpages:
-
-getPages()
-''''''''''
-
-Return the form's pages in the correct order.
-
-Signature::
-
-   public function getPages(): array;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrenderingoptions:
-.. include:: RootRenderableInterface/getRenderingOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrendererclassname:
-.. include:: RootRenderableInterface/getRendererClassName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getlabel:
-.. include:: RootRenderableInterface/getLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettemplatename:
-.. include:: RenderableInterface/getTemplateName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formruntime-getformdefinition:
-
-getFormDefinition()
-'''''''''''''''''''
-
-Get the underlying form definition from the runtime.
-
-Signature::
-
-   public function getFormDefinition(): FormDefinition;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition
-+++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addpage:
-
-addPage()
-'''''''''
-
-Add a new page at the end of the form.
-Instead of this method, you should use ``createPage`` instead.
-
-Signature::
-
-   public function addPage(Page $page);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createpage:
-
-createPage()
-''''''''''''
-
-Create a page with the given $identifier and attach this page to the form.
-
-- Create Page object based on the given $typeName
-- set defaults inside the Page object
-- attach Page object to this form
-- return the newly created Page object
-
-Signature::
-
-   public function createPage(string $identifier, string $typeName = 'Page'): Page;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpages:
-
-getPages()
-''''''''''
-
-Return the form's pages in the correct order.
-
-Signature::
-
-   public function getPages(): array;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-haspagewithindex:
-
-hasPageWithIndex()
-''''''''''''''''''
-
-Check whether a page with the given $index exists.
-
-Signature::
-
-   public function hasPageWithIndex(int $index): bool;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpagebyindex:
-
-getPageByIndex()
-''''''''''''''''
-
-Get the page with the passed index. The first page has index zero.
-If page at $index does not exist, an exception is thrown.
-
-Signature::
-
-   public function getPageByIndex(int $index);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addfinisher:
-
-addFinisher()
-'''''''''''''
-
-Adds the specified finisher to the form.
-Instead of this method, you should use ``createFinisher`` instead.
-
-Signature::
-
-   public function addFinisher(FinisherInterface $finisher);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createfinisher:
-
-createFinisher()
-''''''''''''''''
-
-Create a finisher with the given $identifier and given $options and attach this finisher to the form.
-
-Signature::
-
-   public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getfinishers:
-
-getFinishers()
-''''''''''''''
-
-Gets all finishers of the form.
-
-Signature::
-
-   public function getFinishers(): array;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getelementbyidentifier:
-
-getElementByIdentifier()
-''''''''''''''''''''''''
-
-Get a form element by its identifier.
-If identifier does not exist, returns NULL.
-
-Signature::
-
-   public function getElementByIdentifier(string $elementIdentifier);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-movepageafter:
-
-movePageAfter()
-'''''''''''''''
-
-Move $pageToMove after $referencePage.
-
-Signature::
-
-   public function movePageAfter(Page $pageToMove, Page $referencePage);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-removepage:
-
-removePage()
-''''''''''''
-
-Remove $pageToRemove from the form.
-
-Signature::
-
-   public function removePage(Page $pageToRemove);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-bind:
-
-bind()
-''''''
-
-Bind the current request and response to this form instance, effectively creating a new "instance" of the Form.
-
-Signature::
-
-   public function bind(Request $request): FormRuntime;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getprocessingrule:
-
-getProcessingRule()
-'''''''''''''''''''
-
-Get the processing rule which contains information for property mappings and validations.
-
-Signature::
-
-   public function getProcessingRule(string $propertyPath): ProcessingRule;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettype:
-.. include:: RootRenderableInterface/getType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getidentifier:
-.. include:: RootRenderableInterface/getIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setidentifier:
-.. include:: AbstractRenderable/setIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setoptions:
-.. include:: AbstractRenderable/setOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addvalidator:
-.. include:: FormElementInterface/addValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setdatatype:
-.. include:: FormElementInterface/setDataType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrendererclassname:
-.. include:: RootRenderableInterface/getRendererClassName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrendererclassname:
-
-setRendererClassName()
-''''''''''''''''''''''
-
-Set the renderer class name.
-
-Signature::
-
-   public function setRendererClassName(string $rendererClassName);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrenderingoptions:
-.. include:: RootRenderableInterface/getRenderingOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrenderingoption:
-.. include:: FormElementInterface/setRenderingOption.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getparentrenderable:
-.. include:: RenderableInterface/getParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setparentrenderable:
-.. include:: RenderableInterface/setParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrootform:
-.. include:: AbstractRenderable/getRootForm.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getlabel:
-.. include:: RootRenderableInterface/getLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setlabel:
-.. include:: AbstractRenderable/setLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettemplatename:
-.. include:: RenderableInterface/getTemplateName.rst
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-page:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page
-+++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getelements:
-.. include:: AbstractSection/getElements.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getelementsrecursively:
-.. include:: AbstractSection/getElementsRecursively.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-addelement:
-.. include:: AbstractSection/addElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-createelement:
-
-createElement()
-'''''''''''''''
-
-Create a form element with the given $identifier and attach it to the page.
-
-- Create Form Element object based on the given $typeName
-- set defaults inside the Form Element (based on the parent form's field defaults)
-- attach Form Element to the Page
-- return the newly created Form Element object
-
-Signature::
-
-   public function createElement(string $identifier, string $typeName): FormElementInterface;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-moveelementbefore:
-.. include:: AbstractSection/moveElementBefore.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-moveelementafter:
-.. include:: AbstractSection/moveElementAfter.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-removeelement:
-.. include:: AbstractSection/removeElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-gettype:
-.. include:: RootRenderableInterface/getType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getidentifier:
-.. include:: RootRenderableInterface/getIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setidentifier:
-.. include:: AbstractRenderable/setIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setoptions:
-.. include:: AbstractRenderable/setOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-addvalidator:
-.. include:: FormElementInterface/addValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-createvalidator:
-.. include:: FormElementInterface/createValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setdatatype:
-.. include:: FormElementInterface/setDataType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getrendererclassname:
-.. include:: RootRenderableInterface/getRendererClassName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getrenderingoptions:
-.. include:: RootRenderableInterface/getRenderingOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setrenderingoption:
-.. include:: FormElementInterface/setRenderingOption.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getparentrenderable:
-.. include:: RenderableInterface/getParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setparentrenderable:
-.. include:: RenderableInterface/setParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getrootform:
-.. include:: AbstractRenderable/getRootForm.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-getlabel:
-.. include:: RootRenderableInterface/getLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-setlabel:
-.. include:: AbstractRenderable/setLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-page-gettemplatename:
-.. include:: RenderableInterface/getTemplateName.rst
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-section:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
-++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-initializeformelement:
-.. include:: FormElementInterface/initializeFormElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getuniqueidentifier:
-.. include:: FormElementInterface/getUniqueIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setproperty:
-.. include:: FormElementInterface/setProperty.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getproperties:
-.. include:: FormElementInterface/getProperties.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-isrequired:
-.. include:: FormElementInterface/isRequired.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getelements:
-.. include:: AbstractSection/getElements.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getelementsrecursively:
-.. include:: AbstractSection/getElementsRecursively.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-addelement:
-.. include:: AbstractSection/addElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-createelement:
-
-createElement()
-'''''''''''''''
-
-Create a form element with the given $identifier and attach it to the section.
-
-- Create Form Element object based on the given $typeName
-- set defaults inside the Form Element (based on the parent form's field defaults)
-- attach Form Element to the Section
-- return the newly created Form Element object
-
-Signature::
-
-   public function createElement(string $identifier, string $typeName): FormElementInterface;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-moveelementbefore:
-.. include:: AbstractSection/moveElementBefore.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-moveelementafter:
-.. include:: AbstractSection/moveElementAfter.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-removeelement:
-.. include:: AbstractSection/removeElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-gettype:
-.. include:: RootRenderableInterface/getType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getidentifier:
-.. include:: RootRenderableInterface/getIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setidentifier:
-.. include:: AbstractRenderable/setIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setoptions:
-.. include:: AbstractRenderable/setOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-addvalidator:
-.. include:: FormElementInterface/addValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-createvalidator:
-.. include:: FormElementInterface/createValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setdatatype:
-.. include:: FormElementInterface/setDataType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getrendererclassname:
-.. include:: RootRenderableInterface/getRendererClassName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getrenderingoptions:
-.. include:: RootRenderableInterface/getRenderingOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setrenderingoption:
-.. include:: FormElementInterface/setRenderingOption.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getparentrenderable:
-.. include:: RenderableInterface/getParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setparentrenderable:
-.. include:: RenderableInterface/setParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getrootform:
-.. include:: AbstractRenderable/getRootForm.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-getlabel:
-.. include:: RootRenderableInterface/getLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-setlabel:
-.. include:: AbstractRenderable/setLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-section-gettemplatename:
-.. include:: RenderableInterface/getTemplateName.rst
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement:
-
-TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AbstractFormElement
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-The following classes extends from ``AbstractFormElement`` and therefore contain the following API methods.
-
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
-- TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-initializeformelement:
-.. include:: FormElementInterface/initializeFormElement.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getuniqueidentifier:
-.. include:: FormElementInterface/getUniqueIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getdefaultvalue:
-.. include:: FormElementInterface/getDefaultValue.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdefaultvalue:
-.. include:: FormElementInterface/setDefaultValue.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setproperty:
-.. include:: FormElementInterface/setProperty.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getproperties:
-.. include:: FormElementInterface/getProperties.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-isrequired:
-.. include:: FormElementInterface/isRequired.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettype:
-.. include:: RootRenderableInterface/getType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getidentifier:
-.. include:: RootRenderableInterface/getIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setidentifier:
-.. include:: AbstractRenderable/setIdentifier.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setoptions:
-.. include:: AbstractRenderable/setOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-addvalidator:
-.. include:: FormElementInterface/addValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-createvalidator:
-.. include:: FormElementInterface/createValidator.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdatatype:
-.. include:: FormElementInterface/setDataType.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrendererclassname:
-.. include:: RootRenderableInterface/getRendererClassName.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrenderingoptions:
-.. include:: RootRenderableInterface/getRenderingOptions.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setrenderingoption:
-.. include:: FormElementInterface/setRenderingOption.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getparentrenderable:
-.. include:: RenderableInterface/getParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setparentrenderable:
-.. include:: RenderableInterface/setParentRenderable.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrootform:
-.. include:: AbstractRenderable/getRootForm.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getlabel:
-.. include:: RootRenderableInterface/getLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setlabel:
-.. include:: AbstractRenderable/setLabel.rst
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettemplatename:
-.. include:: RenderableInterface/getTemplateName.rst
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher:
-
-TYPO3\\CMS\\Form\\Domain\\Finishers\\AbstractFinisher
-+++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-The following classes extends from ``AbstractFinisher`` and therefore contain the following API methods.
-
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\ClosureFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\ConfirmationFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\DeleteUploadsFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\EmailFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\FlashMessageFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\RedirectFinisher
-- TYPO3\\CMS\\Form\\Domain\\Finishers\\SaveToDatabaseFinisher
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-execute:
-
-execute()
-'''''''''
-
-Executes the finisher. ``AbstractFinisher::execute()`` call ``$this->executeInternal()`` at the end. Own finisher
-implementations which extends from  ``AbstractFinisher:`` must start their own logic within ``executeInternal()``.
-
-Signature::
-
-   public function execute(FinisherContext $finisherContext);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoptions:
-
-setOptions()
-''''''''''''
-
-Set the finisher options. Instead of directly accessing them, you should rather use ``parseOption()``.
-
-Signature::
-
-   public function setOptions(array $options);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoption:
-
-setOption()
-'''''''''''
-
-Sets a single finisher option.
-
-Signature::
-
-   public function setOption(string $optionName, $optionValue);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-parseoption:
-
-parseOption()
-'''''''''''''
-
-Please read :ref:`Accessing finisher options<concepts-finishers-customfinisherimplementations-accessingoptions>`
-
-Signature::
-
-   protected function parseOption(string $optionName);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishercontext:
-
-TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherContext
-++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-cancel:
-
-cancel()
-''''''''
-
-Cancels the finisher invocation after the current finisher.
-
-Signature::
-
-   public function cancel();
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformruntime:
-
-getFormRuntime()
-''''''''''''''''
-
-The Form Runtime that is associated with the current finisher.
-
-Signature::
-
-   public function getFormRuntime(): FormRuntime;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformvalues:
-
-getFormValues()
-'''''''''''''''
-
-The values of the submitted form (after validation and property mapping).
-
-Signature::
-
-   public function getFormValues(): array;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getfinishervariableprovider:
-
-getFinisherVariableProvider()
-'''''''''''''''''''''''''''''
-
-Returns the current FinisherVariableProvider.
-
-Signature::
-
-   public function getFinisherVariableProvider(): FinisherVariableProvider;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider:
-
-TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherVariableProvider
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-Please read :ref:`Share data between finishers<concepts-finishers-customfinisherimplementations-finishercontext-sharedatabetweenfinishers>`
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-add:
-
-add()
-'''''
-
-Add a variable to the finisher variable provider.
-In case the value is already inside, it is silently overridden.
-
-Signature::
-
-   public function add(string $finisherIdentifier, string $key, $value);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-get:
-
-get()
-'''''
-
-Gets a variable from the finisher variable provider.
-
-Signature::
-
-   public function get(string $finisherIdentifier, string $key, $default = null);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-exists:
-
-exists()
-''''''''
-
-Determine whether there is a variable stored for the given key.
-
-Signature::
-
-   public function exists($finisherIdentifier, $key): bool;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-remove:
-
-remove()
-''''''''
-
-Remove a value from the finisher variable provider.
-
-Signature::
-
-   public function remove(string $finisherIdentifier, string $key);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-configurationservice:
-
-TYPO3\\CMS\\Form\\Domain\\Configuration\\ConfigurationService
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-configurationservice-getprototypeconfiguration:
-
-getPrototypeConfiguration()
-'''''''''''''''''''''''''''
-
-Get the configuration for a given $prototypeName
-
-Signature::
-
-   public function getPrototypeConfiguration(string $prototypeName): array;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory:
-
-TYPO3\\CMS\\Form\\Domain\\Factory\\AbstractFormFactory
-++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory-triggerformbuildingfinished:
-
-triggerFormBuildingFinished()
-'''''''''''''''''''''''''''''
-
-Helper to be called by every ``FormFactory`` which extends from ``AbstractFormFactory`` after
-everything has been built to call the "afterBuildingFinished" hook on all form elements.
-
-Signature::
-
-   protected function triggerFormBuildingFinished(FormDefinition $form);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface:
-
-TYPO3\\CMS\\Form\\Domain\\Factory\\FormFactoryInterface
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface-build:
-
-build()
-'''''''
-
-Build a form definition, depending on some configuration.
-
-Signature::
-
-   public function build(array $configuration, string $prototypeName = null): FormDefinition;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface:
-
-TYPO3\\CMS\\Form\\Domain\\Renderer\\RendererInterface
-+++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-render:
-
-render()
-''''''''
-
-Renders the FormDefinition. This method is expected to call the ``beforeRendering`` hook on each form element::
-
-   public function render(): string;
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setformruntime:
-
-setFormRuntime()
-''''''''''''''''
-
-Set the current ``FormRuntime``::
-
-   public function setFormRuntime(FormRuntime $formRuntime);
-
-
-.. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-getformruntime:
-
-getFormRuntime()
-''''''''''''''''
-
-Get the current ``FormRuntime``::
-
-   public function getFormRuntime(): FormRuntime;
-
-
-.. _apireference-frontendrendering-runtimemanipulation:
-
-Runtime manipulation
---------------------
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks:
-
-Hooks
-^^^^^
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement:
-
-initializeFormElement
-+++++++++++++++++++++
-
-You can connect to this hook and initialize a form element without defining a
-custom implementaion to access the element's ``initializeFormElement`` method.
-You only need a class which connects to this hook. Then detect the form
-element you wish to initialize. For example, you can use this hook to prefill
-form element data from database tables. Note that this hook will be called
-**after** all properties from the prototype configuration are set in the form
-element but **before** the properties from the form definition are set in the
-form element. If you want to prefill form element data after the complete
-form element is configured you should use the
-:ref:`afterBuildingFinished<apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished>` hook.
-
-The initializeFormElement hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::createElement()``
-and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::createElement()``.
-That means the hook will **not** be triggered for ``Pages``. At this point
-you do not have access to submitted form element values.
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
-    * @return void
-    */
-   public function initializeFormElement(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
-   {
-       if ($renderable->getUniqueIdentifier() === 'contactForm-text-1') {
-           $renderable->setDefaultValue('foo');
-       }
-   }
-
-
-.. _useATimestampAsKeyPlease:
-
-What does <useATimestampAsKeyPlease> mean?
-++++++++++++++++++++++++++++++++++++++++++
-
-Timestamps are recommended for hooks such as those of the form framework, as
-seen in the following example::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-Leaving the section ``<useATimestampAsKeyPlease>`` as is is not recommended.
-It does nothing except cause the extension to fail and an error message to be
-delivered. Nor should it be replaced with a function like time(), as the key
-should be unalterable. Instead, replace this section with the current UNIX
-timestamp the moment you are implementing the hook. Check out the following
-example::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][1507018413]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-The purpose of timestamps is to prevent conflicts that arise when two or more
-extensions within one TYPO3 installation use identical keys (e.g.
-``$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement']['foo'])``.
-When timestamps are used, even a one-second difference in the time different
-hooks were connected ensures that one hook does not override the other.
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable:
-
-beforeRemoveFromParentRenderable
-++++++++++++++++++++++++++++++++
-
-This hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormDefinition::removePage()``,  ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::removeElement()``
-and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::removeElement()``
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
-    * @return void
-    */
-   public function beforeRemoveFromParentRenderable(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
-   {
-   }
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished:
-
-afterBuildingFinished
-+++++++++++++++++++++
-
-This hook is called for each form element after the class ``TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory``
-has built the entire form. This hook is triggered just before the
-``FormRuntime`` object is generated. At this point, no run-time information
-(e.g. assigned form values) is yet available. It can, for example, be used to
-generate new form elements within complex forms. The ``ArrayFormFactory`` is
-used by EXT:form via the ``RenderViewHelper`` to render forms using a ``form
-definition`` YAML file. Each form factory implementation must deal with the
-calling of this hook themselves. EXT:form itself uses this hook to initialize
-the property-mapper configuration for ``FileUpload`` elements.
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterBuildingFinished'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
-    * @return void
-    */
-   public function afterBuildingFinished(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
-   {
-   }
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage:
-
-afterInitializeCurrentPage
-++++++++++++++++++++++++++
-
-EXT:form automatically detects the page that should be shown and allow users
-only to jump to the directly following (or previous) pages. This hook enables
-you to implement a custom behavior, for example pages that are shown only when
-other form elements have specific values.
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterInitializeCurrentPage'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
-    * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage
-    * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage
-    * @param mixed $elementValue submitted value of the element *before post processing*
-    * @return null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
-    */
-   public function afterInitializeCurrentPage(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage = null, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage = null, array $requestArguments = []): ?\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
-   {
-       return $currentPage;
-   }
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit:
-
-afterSubmit
-+++++++++++
-
-You can use it for example for dynamic validations which depends on other submitted form element values.
-This hook is invoked by the ``FormRuntime`` for each form element **before** values are property mapped, validated and pushed within the FormRuntime's ``FormState``.
-If the first page is submitted at the first time you cannot access the form element values from the first page by just calling ``$formRuntime['<someOtherFormElementIdentifier>']`` to access
-the submitted form element values from the first page. In this case you can access the submitted raw data through ``$requestArguments``.
-EXT:form itself uses this hook to dynamically add validation errors for ``AdvancedPassword`` form elements.
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterSubmit'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
-    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
-    * @param mixed $elementValue submitted value of the element *before post processing*
-    * @param array $requestArguments submitted raw request values
-    * @return void
-    */
-   public function afterSubmit(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable, $elementValue, array $requestArguments = [])
-   {
-       return $elementValue;
-   }
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering:
-
-beforeRendering
-+++++++++++++++
-
-This is a hook that is invoked by the rendering system before the corresponding element is rendered.
-Use this to access previously submitted values and/or modify the ``FormRuntime`` before an element is outputted to the browser.
-This hook is called after all validations and property mappings are done.
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-connect:
-
-Connect to the hook
-'''''''''''''''''''
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-use:
-
-Use the hook
-''''''''''''
-
-::
-
-   /**
-    * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
-    * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable
-    * @return void
-    */
-   public function beforeRendering(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable)
-   {
-   }
-
-
-.. _apireference-finisheroptions:
-
-Finisher Options
-================
-
-.. _apireference-finisheroptions-closurefinisher:
-
-Closure finisher
-----------------
-
-This finisher can only be used in programmatically-created forms. It makes it
-possible to execute one's own finisher code without having to implement/
-declare this finisher.
-
-Usage through code::
-
-   $closureFinisher = GeneralUtility::makeInstance(ClosureFinisher::class);
-   $closureFinisher->setOption('closure', function($finisherContext) {
-       $formRuntime = $finisherContext->getFormRuntime();
-       // ...
-   });
-   $formDefinition->addFinisher($closureFinisher);
-
-
-.. _apireference-finisheroptions-closurefinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-closurefinisher-options-closure:
-
-closure
-+++++++
-
-:aspect:`Data type`
-      \Closure
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      null
-
-
-.. _apireference-finisheroptions-confirmationfinisher:
-
-Confirmation finisher
----------------------
-
-A simple finisher that outputs a given text.
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: Confirmation
-       options:
-         message: 'Thx for using TYPO3'
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('Confirmation', [
-       'message' => 'foo',
-   ]);
-
-or create manually (not preferred)::
-
-   $confirmationFinisher = GeneralUtility::makeInstance(ConfirmationFinisher::class);
-   $confirmationFinisher->setOptions([
-       'message' => 'foo',
-   ]);
-   $formDefinition->addFinisher($confirmationFinisher);
-
-
-.. _apireference-finisheroptions-confirmationfinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-confirmationfinisher-options-message:
-
-message
-+++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      The form has been submitted.
-
-
-.. _apireference-finisheroptions-deleteuploadsfinisher:
-
-DeleteUploads finisher
-----------------------
-
-This finisher remove the currently submited files.
-Use this finisher e.g after the email finisher if you don't want to keep the files online.
-
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: DeleteUploads
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('DeleteUploads');
-
-or create manually (not preferred)::
-
-   $deleteUploadsFinisher = GeneralUtility::makeInstance(DeleteUploadsFinisher::class);
-   $formDefinition->addFinisher($deleteUploadsFinisher);
-
-
-.. _apireference-finisheroptions-emailfinisher:
-
-Email finisher
---------------
-
-This finisher sends an email to one recipient.
-EXT:form uses 2 EmailFinisher declarations with the identifiers ``EmailToReceiver`` and ``EmailToSender``.
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: EmailToReceiver
-       options:
-         subject: 'Your message'
-         recipientAddress: your.company@example.com
-         recipientName: 'Your Company name'
-         senderAddress: 'form@example.com'
-         senderName: 'form submitter'
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('EmailToReceiver', [
-       'subject' => 'Your message',
-       'recipientAddress' => 'your.company@example.com',
-       'recipientName' => 'Your Company name',
-       'senderAddress' => 'form@example.com',
-       'senderName' => 'form submitter',
-   ]);
-
-or create manually (not preferred)::
-
-   $emailFinisher = GeneralUtility::makeInstance(EmailFinisher::class);
-   $emailFinisher->setOptions([
-       'subject' => 'Your message',
-       'recipientAddress' => 'your.company@example.com',
-       'recipientName' => 'Your Company name',
-       'senderAddress' => 'form@example.com',
-       'senderName' => 'form submitter',
-   ]);
-   $formDefinition->addFinisher($emailFinisher);
-
-
-.. _apireference-finisheroptions-emailfinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-emailfinisher-options-subject:
-
-subject
-+++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Subject of the email
-
-
-.. _apireference-finisheroptions-emailfinisher-options-recipientaddress:
-
-recipientAddress
-++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Email address of the recipient (To)
-
-
-.. _apireference-finisheroptions-emailfinisher-options-recipientname:
-
-recipientName
-+++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty string
-
-:aspect:`Description`
-      Human-readable name of the recipient
-
-
-.. _apireference-finisheroptions-emailfinisher-options-senderaddress:
-
-senderAddress
-+++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Email address of the sender/ visitor (From)
-
-
-.. _apireference-finisheroptions-emailfinisher-options-sendername:
-
-senderName
-++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty string
-
-:aspect:`Description`
-      Human-readable name of the sender
-
-
-.. _apireference-finisheroptions-emailfinisher-options-replytoaddress:
-
-replyToAddress
-++++++++++++++
-
-:aspect:`Data type`
-      string/ array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Email address of to be used as reply-to email (use multiple addresses with an array)
-
-.. note::
-
-   For the moment, the ``form editor`` cannot deal with multiple reply-to addresses (use multiple addresses with an array)
-
-
-.. _apireference-finisheroptions-emailfinisher-options-carboncopyaddress:
-
-carbonCopyAddress
-+++++++++++++++++
-
-:aspect:`Data type`
-      string/ array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Email address of the copy recipient (use multiple addresses with an array)
-
-.. note::
-
-   For the moment, the ``form editor`` cannot deal with multiple copy recipient addresses (use multiple addresses with an array)
-
-
-.. _apireference-finisheroptions-emailfinisher-options-blindcarboncopyaddress:
-
-blindCarbonCopyAddress
-++++++++++++++++++++++
-
-:aspect:`Data type`
-      string/ array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Email address of the blind copy recipient (use multiple addresses with an array)
-
-.. note::
-
-   For the moment, the ``form editor`` cannot deal with multiple blind copy recipient addresses (use multiple addresses with an array)
-
-
-.. _apireference-finisheroptions-emailfinisher-options-format:
-
-format
-++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      html
-
-:aspect:`possible values`
-      html/ plaintext
-
-:aspect:`Description`
-      The format of the email. By default mails are sent as HTML.
-
-
-.. _apireference-finisheroptions-emailfinisher-options-attachuploads:
-
-attachUploads
-+++++++++++++
-
-:aspect:`Data type`
-      bool
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      true
-
-:aspect:`Description`
-      If set, all uploaded items are attached to the email.
-
-
-.. _apireference-finisheroptions-emailfinisher-options-translation-translationfiles:
-
-translation.translationFiles
-++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      string/ array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      If set, this translation file(s) will be used for finisher option translations.
-      If not set, the translation file(s) from the 'Form' element will be used.
-      Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
-
-
-.. _apireference-finisheroptions-emailfinisher-options-translation-language:
-
-translation.language
-++++++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      If not set, the finisher options are translated depending on the current frontend language (if translations exists).
-      This option allows you to force translations for a given language isocode, e.g 'dk' or 'de'.
-      Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
-
-
-.. _apireference-finisheroptions-emailfinisher-options-layoutrootpaths:
-
-layoutRootPaths
-+++++++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Fluid layout paths
-
-
-.. _apireference-finisheroptions-emailfinisher-options-partialrootpaths:
-
-partialRootPaths
-++++++++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Fluid partial paths
-
-
-.. _apireference-finisheroptions-emailfinisher-options-templaterootpaths:
-
-templateRootPaths
-+++++++++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      Fluid template paths; all templates get the current :php:`FormRuntime`
-      assigned as :code:`form` and the :php:`FinisherVariableProvider` assigned
-      as :code:`finisherVariableProvider`.
-
-
-.. _apireference-finisheroptions-emailfinisher-options-variables:
-
-variables
-+++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
-      undefined
-
-:aspect:`Description`
-      associative array of variables which are available inside the Fluid template
-
-
-.. _apireference-finisheroptions-flashmessagefinisher:
-
-FlashMessage finisher
----------------------
-
-A simple finisher that adds a message to the FlashMessageContainer.
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: FlashMessage
-       options:
-         messageTitle: 'Merci'
-         messageCode: 201905041245
-         messageBody: 'Thx for using %s'
-         messageArguments:
-           - 'TYPO3'
-         severity: 0
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('FlashMessage', [
-       'messageTitle' => 'Merci',
-       'messageCode' => 201905041245,
-       'messageBody' => 'Thx for using %s',
-       'messageArguments' => ['TYPO3'],
-       'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
-   ]);
-
-or create manually (not preferred)::
-
-   $flashMessageFinisher = GeneralUtility::makeInstance(FlashMessageFinisher::class);
-   $flashMessageFinisher->setOptions([
-       'messageTitle' => 'Merci',
-       'messageCode' => 201905041245,
-       'messageBody' => 'Thx for using %s',
-       'messageArguments' => ['TYPO3'],
-       'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
-   ]);
-   $formDefinition->addFinisher($flashMessageFinisher);
-
-
-.. _apireference-finisheroptions-flashmessagefinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-flashmessagefinisher-options-messagebody:
-
-messageBody
-+++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Description`
-      The flash message body
-
-
-.. _apireference-finisheroptions-flashmessagefinisher-options-messagetitle:
-
-messageTitle
-++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty string
-
-:aspect:`Description`
-      The flash message title, if needed
-
-
-.. _apireference-finisheroptions-flashmessagefinisher-options-messagearguments:
-
-messageArguments
-++++++++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty array
-
-:aspect:`Description`
-      The flash message arguments, if needed
-
-
-.. _apireference-finisheroptions-flashmessagefinisher-options-messagecode:
-
-messageCode
-+++++++++++
-
-:aspect:`Data type`
-      int
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Description`
-      The flash message code
-
-
-.. _apireference-finisheroptions-flashmessagefinisher-options-severity:
-
-severity
-++++++++
-
-:aspect:`Data type`
-      int
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      \TYPO3\CMS\Core\Messaging\AbstractMessage::OK (0)
-
-:aspect:`Description`
-      The flash message severity code.
-      See \TYPO3\CMS\Core\Messaging\AbstractMessage constants for the codes.
-
-
-.. _apireference-finisheroptions-redirectfinisher:
-
-Redirect finisher
------------------
-
-A simple finisher that redirects to another page.
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: Redirect
-       options:
-         pageUid: 1
-         additionalParameters: 'param1=value1&param2=value2'
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('Redirect', [
-       'pageUid' => 1,
-       'additionalParameters' => 'param1=value1&param2=value2',
-   ]);
-
-or create manually (not preferred)::
-
-   $redirectFinisher = GeneralUtility::makeInstance(RedirectFinisher::class);
-   $redirectFinisher->setOptions([
-       'pageUid' => 1,
-       'additionalParameters' => 'param1=value1&param2=value2',
-   ]);
-   $formDefinition->addFinisher($redirectFinisher);
-
-
-.. _apireference-finisheroptions-redirectfinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-redirectfinisher-options-pageuid:
-
-pageUid
-+++++++
-
-:aspect:`Data type`
-      int
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      1
-
-:aspect:`Description`
-      Redirect to this page uid
-
-
-.. _apireference-finisheroptions-redirectfinisher-options-additionalparameters:
-
-additionalParameters
-++++++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty string
-
-:aspect:`Description`
-      Additional parameters which should be used on the target page
-
-
-.. _apireference-finisheroptions-redirectfinisher-options-delay:
-
-delay
-+++++
-
-:aspect:`Data type`
-      int
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      0
-
-:aspect:`Description`
-      The redirect delay in seconds.
-
-
-.. _apireference-finisheroptions-redirectfinisher-options-statuscode:
-
-statusCode
-++++++++++
-
-:aspect:`Data type`
-      int
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      303
-
-:aspect:`Description`
-      The HTTP status code for the redirect. Default is "303 See Other".
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher:
-
-SaveToDatabase finisher
------------------------
-
-This finisher saves the data from a submitted form into a database table.
-
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: SaveToDatabase
-       options:
-         table: 'fe_users'
-         mode: update
-         whereClause:
-           uid: 1
-         databaseColumnMappings:
-           tstamp:
-             value: '{__currentTimestamp}'
-           pid:
-             value: 1
-         elements:
-           textfield-identifier-1:
-             mapOnDatabaseColumn: 'first_name'
-           textfield-identifier-2:
-             mapOnDatabaseColumn: 'last_name'
-           textfield-identifier-3:
-             mapOnDatabaseColumn: 'username'
-           advancedpassword-1:
-             mapOnDatabaseColumn: 'password'
-             skipIfValueIsEmpty: true
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('SaveToDatabase', [
-       'table' => 'fe_users',
-       'mode' => 'update',
-       'whereClause' => [
-           'uid' => 1,
-       ],
-       'databaseColumnMappings' => [
-           'pid' => ['value' => 1],
-       ],
-       'elements' => [
-           'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
-           'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
-           'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
-           'advancedpassword-1' => [
-               'mapOnDatabaseColumn' => 'password',
-               'skipIfValueIsEmpty' => true,
-           ],
-       ],
-   ]);
-
-or create manually (not preferred)::
-
-   $saveToDatabaseFinisher = GeneralUtility::makeInstance(SaveToDatabaseFinisher::class);
-   $saveToDatabaseFinisher->setOptions([
-       'table' => 'fe_users',
-       'mode' => 'update',
-       'whereClause' => [
-           'uid' => 1,
-       ],
-       'databaseColumnMappings' => [
-           'pid' => ['value' => 1],
-       ],
-       'elements' => [
-           'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
-           'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
-           'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
-           'advancedpassword-1' => [
-               'mapOnDatabaseColumn' => 'password',
-               'skipIfValueIsEmpty' => true,
-           ],
-       ],
-   ]);
-   $formDefinition->addFinisher($saveToDatabaseFinisher);
-
-You can write options as an array to perform multiple database operations.
-
-Usage within form definition
-
-.. code-block:: yaml
-
-   identifier: example-form
-   label: 'example'
-   type: Form
-
-   finishers:
-     -
-       identifier: SaveToDatabase
-       options:
-         1:
-           table: 'my_table'
-           mode: insert
-           databaseColumnMappings:
-             some_column:
-               value: 'cool'
-         2:
-           table: 'my_other_table'
-           mode: update
-           whereClause:
-             pid: 1
-           databaseColumnMappings:
-             some_other_column:
-               value: '{SaveToDatabase.insertedUids.1}'
-   ...
-
-
-Usage through code::
-
-   $formDefinition->createFinisher('SaveToDatabase', [
-       1 => [
-           'table' => 'my_table',
-           'mode' => 'insert',
-           'databaseColumnMappings' => [
-               'some_column' => ['value' => 'cool'],
-           ],
-       ],
-       2 => [
-           'table' => 'my_other_table',
-           'mode' => 'update',
-           'whereClause' => [
-               'pid' => 1,
-           ],
-           'databaseColumnMappings' => [
-               'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
-           ],
-       ],
-   ]);
-
-or create manually (not preferred)::
-
-   $saveToDatabaseFinisher = GeneralUtility::makeInstance(SaveToDatabaseFinisher::class);
-   $saveToDatabaseFinisher->setOptions([
-       1 => [
-           'table' => 'my_table',
-           'mode' => 'insert',
-           'databaseColumnMappings' => [
-               'some_column' => ['value' => 'cool'],
-           ],
-       ],
-       2 => [
-           'table' => 'my_other_table',
-           'mode' => 'update',
-           'whereClause' => [
-               'pid' => 1,
-           ],
-           'databaseColumnMappings' => [
-               'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
-           ],
-       ],
-   ]);
-   $formDefinition->addFinisher($saveToDatabaseFinisher);
-
-
-This performs 2 database operations.
-One insert and one update.
-You can access the inserted uids through '{SaveToDatabase.insertedUids.<theArrayKeyNumberWithinOptions>}'
-If you perform a insert operation, the value of the inserted database row will be stored within the FinisherVariableProvider.
-<theArrayKeyNumberWithinOptions> references to the numeric options.* key.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options:
-
-Options
-^^^^^^^
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-table:
-
-table
-+++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      null
-
-:aspect:`Description`
-      Insert or update values into this table.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-mode:
-
-mode
-++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      'insert'
-
-:aspect:`Possible values`
-      insert/ update
-
-:aspect:`Description`
-      ``insert`` will create a new database row with the values from the submitted form and/or some predefined values. @see options.elements and options.databaseFieldMappings
-
-      ``update`` will update a given database row with the values from the submitted form and/or some predefined values. 'options.whereClause' is then required.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-whereclause:
-
-whereClause
-+++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      Yes, if mode = update
-
-:aspect:`Default value`
-      empty array
-
-:aspect:`Description`
-      This where clause will be used for a database update action
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-elements:
-
-elements
-++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      empty array
-
-:aspect:`Description`
-      Use ``options.elements`` to map form element values to existing database columns.
-      Each key within ``options.elements`` has to match with a form element identifier.
-      The value for each key within ``options.elements`` is an array with additional informations.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-mapondatabasecolumn:
-
-elements.<formElementIdentifier>.mapOnDatabaseColumn
-++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      undefined
-
-:aspect:`Description`
-      The value from the submitted form element with the identifier ``<formElementIdentifier>`` will be written into this database column.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-skipifvalueisempty:
-
-elements.<formElementIdentifier>.skipIfValueIsEmpty
-+++++++++++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      bool
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      false
-
-:aspect:`Description`
-      Set this to true if the database column should not be written if the value from the submitted form element with the identifier
-      ``<formElementIdentifier>`` is empty (think about password fields etc.). Empty means strings without content, whitespace is valid content.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-savefileidentifierinsteadofuid:
-
-elements.<formElementIdentifier>.saveFileIdentifierInsteadOfUid
-+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      bool
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      false
-
-:aspect:`Description`
-      Set this to true if the database column should not be written if the value from the submitted form element with the identifier
-      ``<formElementIdentifier>`` is empty (think about password fields etc.).
-
-      This setting only rules for form elements which creates a FAL object like ``FileUpload`` or ``ImageUpload``.
-      By default, the uid of the FAL object will be written into the database column. Set this to true if you want to store the
-      FAL identifier (1:/user_uploads/some_uploaded_pic.jpg) instead.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-dateformat:
-
-elements.<formElementIdentifier>.dateFormat
-+++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      'U'
-
-:aspect:`Description`
-      If the internal datatype is :php:`\DateTime` which is true for the form element types
-      :yaml:`DatePicker` and :yaml:`Date`, the object needs to be converted into a string value.
-      This option allows you to define the format of the date in case of such a conversion.
-      You can use every format accepted by the PHP :php:`date()` function (https://php.net/manual/en/function.date.php#refsect1-function.date-parameters).
-      The default value is "U" which leads to a Unix timestamp.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings:
-
-databaseColumnMappings
-++++++++++++++++++++++
-
-:aspect:`Data type`
-      array
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      empty array
-
-:aspect:`Description`
-      Use this to map database columns to static values.
-      Each key within ``options.databaseColumnMappings`` has to match with an existing database column.
-      The value for each key within ``options.databaseColumnMappings`` is an array with additional informations.
-
-      This mapping is done *before* the ``options.element`` mapping.
-      This means if you map a database column to a value through ``options.databaseColumnMappings`` and map a submitted
-      form element value to the same database column through ``options.element``, the submitted form element value
-      will override the value you set within ``options.databaseColumnMappings``.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.value:
-
-databaseColumnMappings.<databaseColumnName>.value
-+++++++++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      string
-
-:aspect:`Mandatory`
-      Yes
-
-:aspect:`Default value`
-      undefined
-
-:aspect:`Description`
-      The value which will be written to the database column.
-      You can also use the :ref:`FormRuntime accessor feature<concepts-finishers-customfinisherimplementations-accessingoptions-formruntimeaccessor>` to access every getable property from the ``FormRuntime``
-      In short: use something like ``{<formElementIdentifier>}`` to get the value from the submitted form element with the identifier ``<formElementIdentifier>``.
-
-      If you use the FormRuntime accessor feature within ``options.databaseColumnMappings``, the functionality is nearly identical
-      to the ``options.elements`` configuration variant.
-
-
-.. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.skipifvalueisempty:
-
-databaseColumnMappings.<databaseColumnName>.skipIfValueIsEmpty
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-:aspect:`Data type`
-      bool
-
-:aspect:`Mandatory`
-      No
-
-:aspect:`Default value`
-      false
-
-:aspect:`Description`
-      Set this to true if the database column should not be written if the value from ``options.databaseColumnMappings.<databaseColumnName>.value`` is empty.
-
-
-
-.. _apireference-formeditor:
-
-Form editor
-===========
-
-
-.. _apireference-formeditor-hooks:
-
-Hooks
------
-
-EXT:form implements various hooks so that forms can be manipulated while being
-created or saved.
-
-
-.. _apireference-formeditor-hooks-beforeformcreate:
-
-beforeFormCreate
-^^^^^^^^^^^^^^^^
-
-The form manager calls the 'beforeFormCreate' hook.
-
-
-.. _apireference-formeditor-hooks-beforeformcreate-connect:
-
-Connect to the hook
-+++++++++++++++++++
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormCreate'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-formeditor-hooks-beforeformcreate-use:
-
-Use the hook
-++++++++++++
-
-::
-
-   /**
-    * @param string $formPersistenceIdentifier
-    * @param array $formDefinition
-    * @return array
-    */
-   public function beforeFormCreate(string $formPersistenceIdentifier, array $formDefinition): array
-   {
-       return $formDefinition;
-   }
-
-
-.. _apireference-formeditor-hooks-beforeformduplicate:
-
-beforeFormDuplicate
-^^^^^^^^^^^^^^^^^^^
-
-The form manager call the 'beforeFormDuplicate' hook.
-
-
-.. _apireference-formeditor-hooks-beforeformduplicate-connect:
-
-Connect to the hook
-+++++++++++++++++++
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDuplicate'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-formeditor-hooks-beforeformduplicate-use:
-
-Use the hook
-++++++++++++
-
-::
-
-   /**
-    * @param string $formPersistenceIdentifier
-    * @param array $formDefinition
-    * @return array
-    */
-   public function beforeFormDuplicate(string $formPersistenceIdentifier, array $formDefinition): array
-   {
-       return $formDefinition;
-   }
-
-
-.. _apireference-formeditor-hooks-beforeformdelete:
-
-beforeFormDelete
-^^^^^^^^^^^^^^^^
-
-The form manager call the 'beforeFormDelete' hook.
-
-
-.. _apireference-formeditor-hooks-beforeformdelete-connect:
-
-Connect to the hook
-+++++++++++++++++++
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDelete'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-formeditor-hooks-beforeformdelete-use:
-
-Use the hook
-++++++++++++
-
-::
-
-   /**
-    * @param string $formPersistenceIdentifier
-    * @return void
-    */
-   public function beforeFormDelete(string $formPersistenceIdentifier)
-   {
-   }
-
-
-.. _apireference-formeditor-hooks-beforeformsave:
-
-beforeFormSave
-^^^^^^^^^^^^^^
-
-The form editor call the 'beforeFormSave' hook.
-
-
-.. _apireference-formeditor-hooks-beforeformsave-connect:
-
-Connect to the hook
-+++++++++++++++++++
-
-::
-
-   $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'][<useATimestampAsKeyPlease>]
-       = \VENDOR\YourNamespace\YourClass::class;
-
-
-.. note::
-
-   Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
-   means?
-
-
-.. _apireference-formeditor-hooks-beforeformsave-use:
-
-Use the hook
-++++++++++++
-
-::
-
-   /**
-    * @param string $formPersistenceIdentifier
-    * @param array $formDefinition
-    * @return array
-    */
-   public function beforeFormSave(string $formPersistenceIdentifier, array $formDefinition): array
-   {
-       return $formDefinition;
-   }
-
-
-
-.. _apireference-formeditor-stage:
-
-Stage
------
-
-
-.. _apireference-formeditor-stage-commonabstractformelementtemplates:
-
-Common abstract view form element templates
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The basic idea of the ``abstract view`` is to give a quick overview of the
-configuration of form elements, without having to click them in order to view
-the detailed configuration in the ``Inspector``. The ``form editor`` requires
-for each form element an inline HTML template and the corresponding JavaScript
-code. Information matching inline HTML templates to the appropriate form
-elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
-At this point, the key identifying the form element follows a convention:
-``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
-``form editor`` which inline HTML template should be loaded for the respective
-form element. This template is then cloned via JavaScript, brought to life
-using the form element configuration and shown in the ``Stage`` component.
-
-You can read about how particular form elements are mapped to inline HTML
-templates and how the corresponding JavaScript code are executed :ref:`here <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`.
-
-The form element inline HTML templates and the corresponding JavaScript code
-are configured for reuse. In this way, most form elements you create should be
-able to access the components delivered in EXT:form, without requiring separate
-implementations (at least we hope so). For your own implementations, study
-EXT:form stage templates, which is found under ``Resources/Private/Backend/Partials/FormEditor/Stage/*``.
-The corresponding JavaScript code is found under ``Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js``.
-The method ``_renderTemplateDispatcher()`` shows, which methods will be used to
-render the respective form elements.
-
-Essentially, two different inline HTML templates exists that can be rendered
-with two different JavaScript methods, which are described below. The other
-inline HTML templates are almost all versions of these two basic variants and
-show extra/ other form-element information. The same applies to the
-corresponding JavaScript codes.
-
-
-.. _apireference-formeditor-stage-commonabstractformelementtemplates-simpletemplate:
-
-Stage/SimpleTemplate
-++++++++++++++++++++
-
-This template displays the ``label`` property of the form element. Depending on
-the JavaScript rendering method used, a validator icon will be shown on the
-right as soon as a validator is added to the form element. In this case, the
-used validator labels are likewise displayed, if the form element is selected
-and/ or the cursor hovers over the form element. This template should generally
-be enough for all possible, self-defined form elements.
-
-The ``Stage/SimpleTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
-with the method ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``.
-
-
-.. _apireference-formeditor-stage-commonabstractformelementtemplates-selecttemplate:
-
-Stage/SelectTemplate
-++++++++++++++++++++
-
-This template behaves like the ``Stage/SimpleTemplate`` except that it also
-shows the chosen options labels of the form elements. This is naturally only
-possible for form elements that have ``properties.options.*`` values, e.g.
-``MultiCheckbox``:
-
-.. code-block:: yaml
-
-       type: MultiCheckbox
-       identifier: multicheckbox-1
-       label: 'Multi checkbox'
-       properties:
-         options:
-           value1: label1
-           value2: label2
-
-The template will now list 'label1' and 'label2'.
-
-You can copy this template variant for your own form element, if that form-
-element template also lists array values, which, however, are not found under
-``properties.options.*``. For this purpose, the 'Stage/FileUploadTemplate' is
-an example. It is basically the 'Stage/SelectTemplate' template, with one
-altered property.
-
-In the ``FileUpload`` form element, multiple property values are available
-under ``properties.allowedMimeTypes.*`` as an array.
-
-.. code-block:: yaml
-
-       type: FileUpload
-       identifier: fileupload-1
-       label: 'File upload'
-       properties:
-         saveToFileMount: '1:/user_upload/'
-         allowedMimeTypes:
-           - application/msexcel
-           - application/pdf
-
-Stage/SelectTemplate
-
-.. code-block:: html
-
-   <div data-identifier="multiValueContainer" data-template-property="properties.options">
-
-Stage/FileUploadTemplate
-
-.. code-block:: html
-
-   <div data-identifier="multiValueContainer" data-template-property="properties.allowedMimeTypes">
-
-``data-template-property`` contains the path to the property, which is to be
-read out of the form element and then shown in the template.
-
-The ``Stage/SelectTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
-with the method ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts:
-
-Basic JavaScript Concepts
--------------------------
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events:
-
-Events
-^^^^^^
-
-EXT:form implements the ``publish/subscribe pattern`` to put the event handling
-into effect. To learn more about this pattern, you should read
-https://addyosmani.com/resources/essentialjsdesignpatterns/book/.
-Note that the order of the subscriber is not manipulable and that information
-flow between the subscribers does not exist. All events must be asynchronously
-designed.
-
-Publish an event:
-
-.. code-block:: javascript
-
-   getPublisherSubscriber().publish('eventname', [argumentToPublish1, argumentToPublish2, ...]);
-
-Subscribe to an event:
-
-.. code-block:: javascript
-
-   var subscriberToken = getPublisherSubscriber().subscribe('eventname', function(topic, args) {
-       // args[0] = argumentToPublish1
-       // args[1] = argumentToPublish2
-       // ...
-   });
-
-Unsubscribe an event subscriber:
-
-.. code-block:: javascript
-
-   getPublisherSubscriber().unsubscribe(subscriberToken);
-
-EXT:form itself publishes and subscribes to the following events:
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-ajax-beforesend:
-
-ajax/beforeSend
-+++++++++++++++
-
-Each Ajax request is called before this event is sent. EXT:form uses this event
-to display the spinner icon on the save button.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('ajax/beforeSend', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-ajax-complete:
-
-ajax/complete
-+++++++++++++
-
-Each Ajax request is called after the end of this event. EXT:form uses this
-event to remove the spinner icon on the save button.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('ajax/complete', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-error:
-
-core/ajax/error
-+++++++++++++++
-
-This event is called if the Ajax request, which is used to save the form or to
-render the current page of the form in the ``preview view``, fails. EXT:form
-uses this event to show an error message as a flash message and to show the
-received error text in the ``preview view``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = jqXHR
-    *              args[1] = textStatus
-    *              args[2] = errorThrown
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/ajax/error', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-renderformdefinitionpage-success:
-
-core/ajax/renderFormDefinitionPage/success
-++++++++++++++++++++++++++++++++++++++++++
-
-This event is called if the Ajax request that is used to render the current
-page of the form in the ``preview view`` was successful. EXT:form uses this
-event to display the rendered form in the ``preview view``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = html
-    *              args[1] = pageIndex
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-saveformdefinition-success:
-
-core/ajax/saveFormDefinition/success
-++++++++++++++++++++++++++++++++++++
-
-This event is called if the Ajax request that is used to save the form was
-successful. EXT:form uses this event to display a success message as a flash
-message. The ``form editor`` is also informed that no unsaved content currently
-exists.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = html
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-applicationstate-add:
-
-core/applicationState/add
-+++++++++++++++++++++++++
-
-The addition/ deletion and movement of form elements und property collection
-elements (validators/ finishers) is saved in an internal stack so that the
-undo/ redo function can be implemented. This event is called whenever the
-current state is added to the stack. EXT:form uses this event to reset the
-enabled/ disabled state of the undo/ redo buttons.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = applicationState
-    *              args[1] = stackPointer
-    *              args[2] = stackSize
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/applicationState/add', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-currentlyselectedformelementchanged:
-
-core/currentlySelectedFormElementChanged
-++++++++++++++++++++++++++++++++++++++++
-
-The method ``getFormEditorApp().setCurrentlySelectedFormElement()`` tells the
-``form editor`` which form element should currently be dealt with. This method
-calls this event at the end.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/currentlySelectedFormElementChanged', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged:
-
-core/formElement/somePropertyChanged
-++++++++++++++++++++++++++++++++++++
-
-Each :ref:`FormElement model<apireference-formeditor-basicjavascriptconcepts-formelementmodel>`
-can write properties into the ``FormElement model`` through the methods ``get``
-and ``set``. Each property path can register an event name for the publisher
-through the method ``on``. This event is then always called when a property
-path is written via ``set``. Read :ref:`FormElement model<concepts-formeditor-basicjavascriptconcepts-formelementmodel>`
-for more information. EXT:form automatically registers for all known property
-paths of a form element the event ``core/formElement/somePropertyChanged``.
-This means that every property written via ``set`` calls this event. Among
-other things, EXT:form uses this event for, for example, updating the label of
-a form element in other components (e.g. ``Tree`` component ) when this label
-is changed. Furthermore, any validation errors from form element properties
-are indicated by this event in the ``Tree`` component.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = propertyPath
-    *              args[1] = value
-    *              args[2] = oldValue
-    *              args[3] = formElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-moved:
-
-view/collectionElement/moved
-++++++++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``
-calls this event at the end. EXT:form uses this event to re-render the
-``Inspector`` component as soon as a property collection element (validator/
-finisher) is moved.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = movedCollectionElementIdentifier
-    *              args[1] = previousCollectionElementIdentifier
-    *              args[2] = nextCollectionElementIdentifier
-    *              args[3] = collectionName
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/collectionElement/moved', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-new-added:
-
-view/collectionElement/new/added
-++++++++++++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``
-calls this event at the end. EXT:form uses this event to re-render the
-``Inspector`` component as soon as a property collection element (validator/
-finisher) is created and added.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    *              args[2] = formElement
-    *              args[3] = collectionElementConfiguration
-    *              args[4] = referenceCollectionElementIdentifier
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/collectionElement/new/added', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-removed:
-
-view/collectionElement/removed
-++++++++++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``
-calls this event at the end. EXT:form uses this event to re-render the
-``Inspector`` component as soon as a property collection element (validator/
-finisher) is removed.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    *              args[2] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/collectionElement/removed', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted:
-
-view/formElement/inserted
-+++++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().createAndAddFormElement()`` and
-the event :ref:`view/insertElements/perform/after<apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after>`
-call this event at the end. EXT:form uses this event to set the current
-to-be-processed form element (``getFormEditorApp().setCurrentlySelectedFormElement()``)
-and to re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = newFormElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/formElement/inserted', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-moved:
-
-view/formElement/moved
-++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().moveFormElement()`` calls this
-event at the end.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = movedFormElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/formElement/moved', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-removed:
-
-view/formElement/removed
-++++++++++++++++++++++++
-
-The method ``getFormEditorApp().getViewModel().removeFormElement()`` calls this
-event at the end. EXT:form uses this event to set the current to-be-processed
-form element (``getFormEditorApp().setCurrentlySelectedFormElement()``) and to
-re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = parentFormElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/formElement/removed', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-close-clicked:
-
-view/header/button/close/clicked
-++++++++++++++++++++++++++++++++
-
-The onClick event of the "Close" button in the ``form editor's`` header section
-calls this event. EXT:form uses this event to display a warning message in case
-there are unsaved changes.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/header/button/close/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-newpage-clicked:
-
-view/header/button/newPage/clicked
-++++++++++++++++++++++++++++++++++
-
-The onClick event of the "new page" button in the ``form editor's`` header
-section calls this event. EXT:form uses this event to display the "new page"
-dialog box.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = targetEvent
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-save-clicked:
-
-view/header/button/save/clicked
-+++++++++++++++++++++++++++++++
-
-The onClick event of the "save" button in the ``form editor's`` header section
-calls this event. EXT:form uses this event either to display a dialog box with
-the element in question (if there are validation errors) or to save the ``form
-definition`` (if there are no validation errors).
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/header/button/save/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-header-formsettings-clicked:
-
-view/header/formSettings/clicked
-++++++++++++++++++++++++++++++++
-
-The onClick event of the "settings"  button in the ``form editor's`` header
-section calls this event. EXT:form uses this event to select the root form
-element.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/header/formSettings/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after:
-
-view/insertElements/perform/after
-+++++++++++++++++++++++++++++++++
-
-This event is called from the "new element" dialog box upon selection of a form
-element:
-
-- if "After" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
-- if the "Create new element" button in the form-element toolbar for non-composite elements is clicked.
-
-EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``)
-and then move (``getFormEditorApp().getViewModel().moveFormElement()``) it
-below the currently selected element (sibling). At the end of this event, the
-event :ref:`view/formElement/inserted<apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted>`
-is called. The event ``view/formElement/inserted`` in ``getFormEditorApp().getViewModel().createAndAddFormElement()``
-was previously deactivated.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementType
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/insertElements/perform/after', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-bottom:
-
-view/insertElements/perform/bottom
-++++++++++++++++++++++++++++++++++
-
-This event is called from the "new element" dialog box upon selection of a form
-element:
-
-- if, in the ``abstract view`` mode, the "Create new element" button at the end of the ``Stage`` component is clicked.
-
-EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
-This element is always created as the last element of the currently selected
-page.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementType
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-inside:
-
-view/insertElements/perform/inside
-++++++++++++++++++++++++++++++++++
-
-This event is called from the "new element" dialog box upon selection of a form
-element:
-
-- if "Inside" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
-
-EXT:form uses this event to create a new form element as a child element of the
-currently selected element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementType
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/insertElements/perform/inside', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-insertpages-perform:
-
-view/insertPages/perform
-++++++++++++++++++++++++
-
-This event is called from the "new element" dialog box upon selection of a page
-element:
-
-- if the "Create new page" icon in the header section is clicked.
-- if the "Create new page" button in the ``Tree`` component is clicked.
-
-EXT:form uses this event to create a new page after the currently selected page
-(``getFormEditorApp().getViewModel().createAndAddFormElement()``).
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementType
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/insertPages/perform', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-existing-selected:
-
-view/inspector/collectionElement/existing/selected
-++++++++++++++++++++++++++++++++++++++++++++++++++
-
-The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
-and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
-are used to display the available validators/ finishers for a form element as a
-select box. Furthermore, these ``inspector editors`` indicate that in the
-``form definition``, validators/ finishers for the currently selected element
-already exist. This occurs through the event ``view/inspector/collectionElement/existing/selected``.
-EXT:form uses this event to render these validators/ finishers and their
-tentatively configured ``inspector editors`` (``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``).
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-new-selected:
-
-view/inspector/collectionElement/new/selected
-+++++++++++++++++++++++++++++++++++++++++++++
-
-The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
-and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
-are used to display the available validators/ finishers for a form element as a
-select box. The onChange event of the select box then calls this event. In
-addition, the ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
-calls this event when a checkbox is chosen. EXT:form uses this event to add and
-render the validator/ finisher of the ``form definition`` via ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-dnd-update:
-
-view/inspector/collectionElements/dnd/update
-++++++++++++++++++++++++++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
-the ``view/inspector/collectionElements/dnd/update`` event if a property
-collection element in the ``Inspector`` component is sorted. EXT:form uses this
-event to move the validator/ finisher in the ``form definition`` via the method
-``getFormEditorApp().getViewModel().movePropertyCollectionElement()``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = movedCollectionElementIdentifier
-    *              args[1] = previousCollectionElementIdentifier
-    *              args[2] = nextCollectionElementIdentifier
-    *              args[3] = collectionName
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-editor-insert-perform:
-
-view/inspector/editor/insert/perform
-++++++++++++++++++++++++++++++++++++
-
-The methods ``getFormEditorApp().getViewModel().renderInspectorEditors()`` (to
-render all ``inspector editors`` for a form element) and ``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``
-(to render the ``inspector editors`` for a validator/ finisher) call this event
-at the end. Strictly speaking, the ``Inspector`` component in the method
-``_renderEditorDispatcher()`` calls this event.
-Each ``inspector editor`` has the property :ref:`templateName <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.templatename>`,
-which gives the ``form editor`` two pieces of information. On the one hand the
-``templateName`` must match with a key within the :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
-The ``form editor`` can consequently load a corresponding inline HTML template
-for the ``inspector editor``. On the other hand, the ``Inspector`` component
-must be told which JavaScript code should be executed for the
-``inspector editor``. For the ``inspector editors`` delivered with EXT:form,
-this occurs within the method ``_renderEditorDispatcher()``.
-An existing hard-coded list of known ``inspector editors`` determines, by means
-of the property ``templateName``, which corresponding JavaScript method should
-be executed for the ``inspector editor``. At the end, the event
-``view/inspector/editor/insert/perform`` is called. If you wish to implement
-your own ``inspector editor``, you can use this event to execute in
-:ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
-the corresponding JavaScript code, with the help of the property
-``templateName``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = editorConfiguration
-    *              args[1] = editorHtml
-    *              args[2] = collectionElementIdentifier
-    *              args[3] = collectionName
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
-   });
-
-A simple example that registers a custom ``inspector editor`` called 'Inspector-MyCustomInspectorEditor' and adds it to text form elements:
-
-.. code-block:: yaml
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formEditor:
-               dynamicJavaScriptModules:
-                 additionalViewModelModules:
-                   10: 'TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel'
-               formEditorFluidConfiguration:
-                 partialRootPaths:
-                   100: 'EXT:my_site_package/Resources/Private/Backend/Partials/FormEditor/'
-               formEditorPartials:
-                 Inspector-MyCustomInspectorEditor: 'Inspector/MyCustomInspectorEditor'
-             formElementsDefinition:
-               Text:
-                 formEditor:
-                   editors:
-                     600:
-                       templateName: 'Inspector-MyCustomInspectorEditor'
-                       ...
-
-.. code-block:: javascript
-   :emphasize-lines: 107-116
-
-   /**
-    * Module: @typo3/my-site-package/backend/form-editor/view-model
-    */
-   define(['jquery',
-           'TYPO3/CMS/Form/Backend/FormEditor/Helper'
-           ], function($, Helper) {
-           'use strict';
-
-       return (function($, Helper) {
-
-           /**
-            * @private
-            *
-            * @var object
-            */
-           var _formEditorApp = null;
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getFormEditorApp() {
-               return _formEditorApp;
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getPublisherSubscriber() {
-               return getFormEditorApp().getPublisherSubscriber();
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getUtility() {
-               return getFormEditorApp().getUtility();
-           };
-
-           /**
-            * @private
-            *
-            * @param object
-            * @return object
-            */
-           function getHelper() {
-               return Helper;
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getCurrentlySelectedFormElement() {
-               return getFormEditorApp().getCurrentlySelectedFormElement();
-           };
-
-           /**
-            * @private
-            *
-            * @param mixed test
-            * @param string message
-            * @param int messageCode
-            * @return void
-            */
-           function assert(test, message, messageCode) {
-               return getFormEditorApp().assert(test, message, messageCode);
-           };
-
-           /**
-            * @private
-            *
-            * @return void
-            * @throws 1491643380
-            */
-           function _helperSetup() {
-               assert('function' === $.type(Helper.bootstrap),
-                   'The view model helper does not implement the method "bootstrap"',
-                   1491643380
-               );
-               Helper.bootstrap(getFormEditorApp());
-           };
-
-           /**
-            * @private
-            *
-            * @return void
-            */
-           function _subscribeEvents() {
-               /**
-                * @private
-                *
-                * @param string
-                * @param array
-                *              args[0] = editorConfiguration
-                *              args[1] = editorHtml
-                *              args[2] = collectionElementIdentifier
-                *              args[3] = collectionName
-                * @return void
-                */
-               getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
-                   if (args[0]['templateName'] === 'Inspector-MyCustomInspectorEditor') {
-                       renderMyCustomInspectorEditor(
-                           args[0],
-                           args[1],
-                           args[2],
-                           args[3]
-                       );
-                   }
-               });
-           };
-
-           /**
-            * @private
-            *
-            * @param object editorConfiguration
-            * @param object editorHtml
-            * @param string collectionElementIdentifier
-            * @param string collectionName
-            * @return void
-            */
-           function renderMyCustomInspectorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-               // do cool stuff
-           });
-
-           /**
-            * @public
-            *
-            * @param object formEditorApp
-            * @return void
-            */
-           function bootstrap(formEditorApp) {
-               _formEditorApp = formEditorApp;
-               _helperSetup();
-               _subscribeEvents();
-           };
-
-           /**
-            * Publish the public methods.
-            * Implements the "Revealing Module Pattern".
-            */
-           return {
-               bootstrap: bootstrap
-           };
-       })($, Helper);
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-removecollectionelement-perform:
-
-view/inspector/removeCollectionElement/perform
-++++++++++++++++++++++++++++++++++++++++++++++
-
-The ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
-calls this event, if the checkbox is deselected. EXT:form uses this event to
-remove the configured required validator ('NotEmpty') from the ``form
-definition`` through the method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    *              args[2] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-close-perform:
-
-view/modal/close/perform
-++++++++++++++++++++++++
-
-If you try to close the ``form editor`` with unsaved content, a dialog box
-appears, asking whether you really wish to close it. If you confirm it, this
-event is called in the ``check box`` component. EXT:form uses this event to
-close the ``form editor`` and return to the ``form manager``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/modal/close/perform', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removecollectionelement-perform:
-
-view/modal/removeCollectionElement/perform
-++++++++++++++++++++++++++++++++++++++++++
-
-If you try to remove a validator/ finisher by clicking the remove icon, a
-dialog box appears, asking you to confirm this action. If confirmed, this event
-is called in the ``check box`` component. EXT:form uses this event to remove
-the validator/ finisher from the ``form definition`` through the method
-``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = collectionElementIdentifier
-    *              args[1] = collectionName
-    *              args[2] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/modal/removeCollectionElement/perform', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removeformelement-perform:
-
-view/modal/removeFormElement/perform
-++++++++++++++++++++++++++++++++++++
-
-If you try to remove a form element by clicking the remove icon, a dialog box
-appears, asking you to confirm this action. If confirmed, this event is called
-in the ``check box`` component. EXT:form uses this event to remove the form
-element from the ``form definition`` via the method ``getFormEditorApp().getViewModel().removeFormElement()``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/modal/removeFormElement/perform', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-validationerrors-element-clicked:
-
-view/modal/validationErrors/element/clicked
-+++++++++++++++++++++++++++++++++++++++++++
-
-If a form element contains a validation error and you try to save the form, a
-dialog box appears, listing all form elements with validation errors. One such
-form element can be clicked in this dialog box. This event is called by
-clicking a form element in the dialog box. EXT:form uses this event to select
-and show this form element.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/modal/validationErrors/element/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationnext-clicked:
-
-view/paginationNext/clicked
-+++++++++++++++++++++++++++
-
-This event is called if the 'pagination next' button in the ``Stage``
-component's header section is clicked. EXT:form uses this event to render the
-next page of the form.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/paginationNext/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationprevious-clicked:
-
-view/paginationPrevious/clicked
-+++++++++++++++++++++++++++++++
-
-This event is called, if the 'pagination previous' button in the ``Stage``
-component's header section is clicked. EXT:form uses this event to render the
-previous page of the form.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/paginationPrevious/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-ready:
-
-view/ready
-++++++++++
-
-EXT:form makes it possible to load :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
-If all modules are loaded, the view-model method ``_loadAdditionalModules``
-calls this event. EXT:form uses this event to remove the preloader icon and
-finally initialize the ``form editor``.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/ready', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-redobutton-clicked:
-
-view/redoButton/clicked
-+++++++++++++++++++++++
-
-This event is called if the redo button in the ``form editor`` header is
-clicked. The addition/ deletion and movement of form elements and property
-collection elements (validators/ finishers) is saved in an internal stack in
-order to reset the undo/ redo functionality. EXT:form uses this event to reset
-this stack to the previous state.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/redoButton/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-button-newelement-clicked:
-
-view/stage/abstract/button/newElement/clicked
-+++++++++++++++++++++++++++++++++++++++++++++
-
-This event is called if the "Create new element" button at the end of the
-``Stage`` component in the ``abstract view`` mode is clicked. EXT:form uses
-this event to display the "new element" dialog box.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = targetEvent
-    *              args[1] = configuration
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/button/newElement/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-change:
-
-view/stage/abstract/dnd/change
-++++++++++++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'change' event from 'jquery.mjs.nestedSortable' calls
-the ``view/stage/abstract/dnd/change`` event in the ``Stage`` component in the
-``abstract view`` mode if form elements are sorted. EXT:form uses this event to
-set various CSS classes during the drag-and-drop process.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = placeholderDomElement
-    *              args[1] = parentFormElementIdentifierPath
-    *              args[2] = enclosingCompositeFormElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/change', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-start:
-
-view/stage/abstract/dnd/start
-+++++++++++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'start' event from 'jquery.mjs.nestedSortable' calls
-the ``view/stage/abstract/dnd/start`` event in the ``Stage`` component in the
-``abstract view`` mode if form elements are sorted. EXT:form uses this event to
-set various CSS classes at the start of the drag-and-drop process.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = draggedFormElementDomElement
-    *              args[1] = draggedFormPlaceholderDomElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/start', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-stop:
-
-view/stage/abstract/dnd/stop
-++++++++++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'stop' event from 'jquery.mjs.nestedSortable' calls the
-``view/stage/abstract/dnd/stop`` event in the ``Stage`` component in the
-``abstract view`` mode if form elements are sorted. EXT:form uses this event to
-to re-render the ``Tree``, ``Stage`` and ``Inspector`` components at the end of
-the drag-and-drop process and to select the moved form element.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = draggedFormElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/stop', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-update:
-
-view/stage/abstract/dnd/update
-++++++++++++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
-the ``view/stage/abstract/dnd/update`` event in the ``Stage`` component in the
-``abstract view`` mode if form elements are sorted. EXT:form uses this event
-to move the form element in the ``form definition`` accordingly at the end of
-the drag-and-drop process.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = movedDomElement
-    *              args[1] = movedFormElementIdentifierPath
-    *              args[2] = previousFormElementIdentifierPath
-    *              args[3] = nextFormElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/dnd/update', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-elementtoolbar-button-newelement-clicked:
-
-view/stage/abstract/elementToolbar/button/newElement/clicked
-++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-
-This event is called if the "Create new element" button in the form-element
-toolbar or "Inside" or "After" in the split button is clicked. EXT:form uses
-this event to display the "New element" dialog box.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = targetEvent
-    *              args[1] = configuration
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/elementToolbar/button/newElement/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-postprocess:
-
-view/stage/abstract/render/postProcess
-++++++++++++++++++++++++++++++++++++++
-
-This event is called after the ``abstract view`` of the ``Stage`` component has
-been rendered. EXT:form uses this event to render the undo/ redo buttons.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/render/postProcess', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-preprocess:
-
-view/stage/abstract/render/preProcess
-+++++++++++++++++++++++++++++++++++++
-
-This event is called before the ``abstract view`` of the ``Stage`` component is
-rendered.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/render/preProcess', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform:
-
-view/stage/abstract/render/template/perform
-+++++++++++++++++++++++++++++++++++++++++++
-
-The methods ``getFormEditorApp().getViewModel().renderAbstractStageArea()``
-call this event. Strictly speaking, the ``Stage`` component in the method
-``_renderTemplateDispatcher()`` calls this event. The ``form editor`` requires
-for each form element an inline HTML template the corresponding JavaScript
-code. Information matching inline HTML templates to the appropriate form
-elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
-At this point, the key identifying the form element follows a convention:
-``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
-``form editor`` which inline HTML template should be loaded for the respective
-form element. The ``_renderTemplateDispatcher()`` method then identifies, by
-means of the form element's ``<formElementTypeIdentifier>``, the corresponding
-JavaScript code to fill the inline HTML template with life.
-``_renderTemplateDispatcher()`` contains a hard-coded list with the
-``<formElementTypeIdentifier>`` that is brought in with the EXT:form, and it
-renders the inline HTML templates accordingly. At the end, the
-``view/stage/abstract/render/template/perform`` event is called. If you wish to
-implement your own form element and show it in the ``form editor``, this event
-can be used to execute in :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`
-the corresponding JavaScript code, with the help of the ``<formElementTypeIdentifier>``.
-This is generally enough to allow the ``Stage/SimpleTemplate`` and/ or
-``Stage/SelectTemplate`` inline HTML template to be rendered for your own form
-element and, in the JavaScript code, to access the ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``
-and/ or ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``
-method delivered with EXT:form. An overview over the functionality of the
-formEditorPartials for the ``<formElementTypeIdentifier>`` and its JavaScript
-code is found :ref:`here <apireference-formeditor-stage-commonabstractformelementtemplates>`.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElement
-    *              args[1] = template
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/abstract/render/template/perform', function(topic, args) {
-   });
-
-A simple example reusing the EXT:form inline HTML template ``Stage/SelectTemplate`` and the EXT:form JavaScript code ``renderSelectTemplates()``
-for a custom form element with ``<formElementTypeIdentifier>`` = 'GenderSelect'.
-In this example, 'GenderSelect' is basically a radio button form element with some predefined options.
-
-.. code-block:: yaml
-   :emphasize-lines: 11
-
-   TYPO3:
-     CMS:
-       Form:
-         prototypes:
-           standard:
-             formEditor:
-               dynamicJavaScriptModules:
-                 additionalViewModelModules:
-                   10: '@typo3/my-site-package/backend/form-editor/view-model.js'
-               formEditorPartials:
-                 FormElement-GenderSelect: 'Stage/SelectTemplate'
-             formElementsDefinition:
-               GenderSelect:
-                 __inheritances:
-                   10: 'TYPO3.CMS.Form.prototypes.standard.formElementsDefinition.RadioButton'
-                 renderingOptions:
-                   templateName: 'RadioButton'
-                 properties:
-                   options:
-                     f: 'Female'
-                     m: 'Male'
-                     u: 'Unicorn'
-                     a: 'Alien'
-                 formEditor:
-                   label: 'Gender Select'
-                   group: select
-                   groupSorting: 9000
-                   predefinedDefaults:
-                     properties:
-                       options:
-                         f: 'Female'
-                         m: 'Male'
-                         u: 'Unicorn'
-                         a: 'Alien'
-                   editors:
-                     300: null
-
-.. code-block:: javascript
-   :emphasize-lines: 105-109
-
-   /**
-    * Module: @typo3/my-site-package/backend/form-editor/view-model
-    */
-   define(['jquery',
-           'TYPO3/CMS/Form/Backend/FormEditor/Helper'
-           ], function($, Helper) {
-           'use strict';
-
-       return (function($, Helper) {
-
-           /**
-            * @private
-            *
-            * @var object
-            */
-           var _formEditorApp = null;
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getFormEditorApp() {
-               return _formEditorApp;
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getPublisherSubscriber() {
-               return getFormEditorApp().getPublisherSubscriber();
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getUtility() {
-               return getFormEditorApp().getUtility();
-           };
-
-           /**
-            * @private
-            *
-            * @param object
-            * @return object
-            */
-           function getHelper() {
-               return Helper;
-           };
-
-           /**
-            * @private
-            *
-            * @return object
-            */
-           function getCurrentlySelectedFormElement() {
-               return getFormEditorApp().getCurrentlySelectedFormElement();
-           };
-
-           /**
-            * @private
-            *
-            * @param mixed test
-            * @param string message
-            * @param int messageCode
-            * @return void
-            */
-           function assert(test, message, messageCode) {
-               return getFormEditorApp().assert(test, message, messageCode);
-           };
-
-           /**
-            * @private
-            *
-            * @return void
-            * @throws 1491643380
-            */
-           function _helperSetup() {
-               assert('function' === $.type(Helper.bootstrap),
-                   'The view model helper does not implement the method "bootstrap"',
-                   1491643380
-               );
-               Helper.bootstrap(getFormEditorApp());
-           };
-
-           /**
-            * @private
-            *
-            * @return void
-            */
-           function _subscribeEvents() {
-               /**
-                * @private
-                *
-                * @param string
-                * @param array
-                *              args[0] = formElement
-                *              args[1] = template
-                * @return void
-                */
-               getPublisherSubscriber().subscribe('view/stage/abstract/render/template/perform', function(topic, args) {
-                   if (args[0].get('type') === 'GenderSelect') {
-                       getFormEditorApp().getViewModel().getStage().renderSelectTemplates(args[0], args[1]);
-                   }
-               });
-           };
-
-           /**
-            * @public
-            *
-            * @param object formEditorApp
-            * @return void
-            */
-           function bootstrap(formEditorApp) {
-               _formEditorApp = formEditorApp;
-               _helperSetup();
-               _subscribeEvents();
-           };
-
-           /**
-            * Publish the public methods.
-            * Implements the "Revealing Module Pattern".
-            */
-           return {
-               bootstrap: bootstrap
-           };
-       })($, Helper);
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-element-clicked:
-
-view/stage/element/clicked
-++++++++++++++++++++++++++
-
-This event is called from the ``Stage`` component when a form element is
-clicked. EXT:form uses this event to select this element and to display the
-form-element toolbar. In addition, the ``Tree`` and ``Inspector`` components
-are re-rendered.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/element/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-panel-clicked:
-
-view/stage/panel/clicked
-++++++++++++++++++++++++
-
-This event is called if the header section of the ``Stage`` component is
-clicked.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/panel/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-preview-render-postprocess:
-
-view/stage/preview/render/postProcess
-+++++++++++++++++++++++++++++++++++++
-
-This event is called after the ``preview view`` of the ``Stage`` component has
-been rendered. EXT:form uses this event to render the undo/ redo buttons.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/stage/preview/render/postProcess', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-button-newpage-clicked:
-
-view/structure/button/newPage/clicked
-+++++++++++++++++++++++++++++++++++++
-
-This event is called from the onClick event of the ``Tree`` component's "Create
-new page" button. EXT:form uses this event to display the "new page" dialog
-box.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = targetEvent
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/structure/button/newPage/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-renew-postprocess:
-
-view/structure/renew/postProcess
-++++++++++++++++++++++++++++++++
-
-This event is called from the view-model after the ``Tree`` component has been
-re-rendered. EXT:form uses this event to display potential validation errors
-from form elements in the ``Tree`` component.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/structure/renew/postProcess', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-structure-root-selected:
-
-view/structure/root/selected
-++++++++++++++++++++++++++++
-
-This event is called if the root form element in the ``Tree`` component is
-clicked. EXT:form uses this event to re-render the ``Stage``, ``Inspector`` and
-``Tree`` components.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/structure/root/selected', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-change:
-
-view/tree/dnd/change
-++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'change' event from 'jquery.mjs.nestedSortable' calls
-the ``view/tree/dnd/change`` event in der ``Tree`` component if form elements
-are sorted. EXT:form uses this event to set various CSS classes during the drag
--and-drop process.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = placeholderDomElement
-    *              args[1] = parentFormElementIdentifierPath
-    *              args[2] = enclosingCompositeFormElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/tree/dnd/change', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-stop:
-
-view/tree/dnd/stop
-++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'stop' event from 'jquery.mjs.nestedSortable' calls the
-``view/tree/dnd/stop`` event in the ``Tree`` component if form elements are
-sorted. EXT:form uses this event to re-render ``Tree``, ``Stage`` and
-``Inspector`` components at the end of the drag-and-drop process and to select
-the moved form element.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = draggedFormElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/tree/dnd/stop', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-dnd-update:
-
-view/tree/dnd/update
-++++++++++++++++++++
-
-EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
-drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
-the ``view/tree/dnd/update`` event in der ``Tree`` component if form elements
-are sorted. EXT:form uses this event to move the form element in the ``form
-definition`` accordingly at the end of the drag-and-drop process.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = movedDomElement
-    *              args[1] = movedFormElementIdentifierPath
-    *              args[2] = previousFormElementIdentifierPath
-    *              args[3] = nextFormElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/tree/dnd/update', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-node-clicked:
-
-view/tree/node/clicked
-++++++++++++++++++++++
-
-This event is called from the ``Tree`` component if a form element is clicked.
-EXT:form uses this event to re-render the ``Stage`` and ``Inspector``
-components and select the form element.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = formElementIdentifierPath
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/tree/node/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-tree-render-listitemadded:
-
-view/tree/render/listItemAdded
-++++++++++++++++++++++++++++++
-
-This event is called by the ``Tree`` component for each form element as soon as
-it is added to the tree.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    *              args[0] = listItem
-    *              args[1] = formElement
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/tree/render/listItemAdded', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-undobutton-clicked:
-
-view/undoButton/clicked
-+++++++++++++++++++++++
-
-This event is called when the undo button is clicked in the ``form editor``
-header. The history of adding / deleting and moving form elements and property
-collection elements (validators/ finishers) is stored in an internal stack to
-implement the undo / redo functionality. EXT:form uses this event to set this
-stack to the next state.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/undoButton/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-viewmodebutton-abstract-clicked:
-
-view/viewModeButton/abstract/clicked
-++++++++++++++++++++++++++++++++++++
-
-This event is called when the abstract view button is clicked in the header
-area of the ``Stage`` component. EXT:form uses this event to render the
-``abstract view`` in the ``Stage`` component.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/viewModeButton/abstract/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-events-view-viewmodebutton-preview-clicked:
-
-view/viewModeButton/preview/clicked
-+++++++++++++++++++++++++++++++++++
-
-This event is called when the preview button is clicked in the header area of
-the ``Stage`` component. EXT:form uses this event to render the ``preview
-view`` in the ``Stage`` component.
-
-Subscribe to the event:
-
-.. code-block:: javascript
-
-   /**
-    * @private
-    *
-    * @param string
-    * @param array
-    * @return void
-    */
-   getPublisherSubscriber().subscribe('view/viewModeButton/preview/clicked', function(topic, args) {
-   });
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel:
-
-FormElement model
-^^^^^^^^^^^^^^^^^
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-parentrenderable:
-
-Property: __parentRenderable
-++++++++++++++++++++++++++++
-
-__parentRenderable includes the parent element as ``FormElement model``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-identifierpath:
-
-Property: __identifierPath
-++++++++++++++++++++++++++
-
-Internally, all form elements are identified by their 'identifier' property,
-which must be unique for each form. The ``__identifierPath`` property contains
-the path to the element (as seen from the first element), separated by a ``/``.
-Using this path, you can access the element directly through an API method.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get:
-
-Method: get()
-+++++++++++++
-
-Each property of the ``FormElement model`` can be accessed by the ``get()``
-method through the property path (separated by ``.``). Prerequisite for this
-is that all levels up to the target property are objects.
-
-Example of a ``FormElement model``:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {
-         "placeholder": "Name"
-       }
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "NotEmpty"
-       }
-     ]
-   }
-
-Access to ``properties.fluidAdditionalAttributes.placeholder``:
-
-.. code-block:: javascript
-
-   // value = 'Name'
-   var value = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').get('properties.fluidAdditionalAttributes.placeholder');
-
-Two exceptions are the two arrays of "finishers" / "validators" (``property
-collections``) and the ``renderables``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties:
-
-Accessing property collection properties
-''''''''''''''''''''''''''''''''''''''''
-
-Property collection are identified as form elements through the property
-``identifier``. Because property collection properties are in an array and
-their positions in the array are potentially unknown, the ``getFormEditorApp().buildPropertyPath()``
-method exists. This can be used to access a property of a property collection
-item via its ``identifier``.
-
-Example of a ``FormElement model``:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {
-         "placeholder": "Name"
-       }
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "StringLength"
-         "options": {
-           "minimum": "1",
-           "maximum": "2"
-         }
-       }
-     ]
-   }
-
-Access to ``options.minimum`` of the validator ``StringLength``:
-
-.. code-block:: javascript
-
-   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
-   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
-   // value = 1
-   var value = formElement.get(propertyPath);
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-renderables:
-
-Accessing renderables
-'''''''''''''''''''''
-
-Like ``property collections``, ``renderables`` (the child elements) are also in
-an array and their position in the array is potentially unknown. Direct access
-to child elements through the  ``get()`` method is impossible.
-``formElement.get('renderables')`` supplies an array with the ``FormElement
-models`` of the child elements. You must then loop over this array. Access to a
-specific child element should be done using ``getFormEditorApp().getFormElementByIdentifierPath()``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set:
-
-Method: set()
-+++++++++++++
-
-Any property of the ``FormElement model`` can be written using the ``set()``
-method by means of the property path (separated by ``.``).
-
-Example of a ``FormElement model``:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {
-         "placeholder": "Name"
-       }
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "NotEmpty"
-       }
-     ]
-   }
-
-Set the property ``properties.fluidAdditionalAttributes.placeholder``:
-
-.. code-block:: javascript
-
-   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
-
-Example of the ``FormElement model`` after the ``set()`` operation:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {
-         "placeholder": "New Placeholder"
-       }
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "NotEmpty"
-       }
-     ]
-   }
-
-Two exceptions are the two arrays of "finishers" / "validators" (``property
-collections``) and the ``renderables``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-propertycollectionproperties:
-
-Setting property collection properties
-''''''''''''''''''''''''''''''''''''''
-
-In principle, the same applies here as for :ref:`get property collection properties<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties>`.
-
-Set the property ``options.minimum`` of the validator ``StringLength``:
-
-.. code-block:: javascript
-
-   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
-   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
-   formElement.set(propertyPath, '2');
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-renderables:
-
-Setting renderables
-'''''''''''''''''''
-
-To add child form elements to a ``FormElement model``, the appropriate API
-methods should be used:
-
-- getFormEditorApp().createAndAddFormElement()
-- getFormEditorApp().addFormElement()
-- getFormEditorApp().moveFormElement()
-- getFormEditorApp().removeFormElement()
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset:
-
-Method: unset()
-+++++++++++++++
-
-Any property of the ``FormElement model`` can be deleted using the method
-``unset()`` by means of the property path (separated by ``.``).
-
-Example of a ``FormElement model``:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {
-         "placeholder": "Name"
-       }
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "NotEmpty"
-       }
-     ]
-   }
-
-Delete the property ``properties.fluidAdditionalAttributes.placeholder``:
-
-.. code-block:: javascript
-
-   // value = 'Name'
-   var value = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').unset('properties.fluidAdditionalAttributes.placeholder');
-
-Example of the ``FormElement model`` after the ``unset()`` operation:
-
-.. code-block:: javascript
-
-   {
-     "identifier": "name",
-     "defaultValue": "",
-     "label": "Name",
-     "type": "Text",
-     "properties": {
-       "fluidAdditionalAttributes": {}
-     },
-     "__parentRenderable": "example-form/page-1 (filtered)",
-     "__identifierPath": "example-form/page-1/name",
-     "validators": [
-       {
-         "identifier": "NotEmpty"
-       }
-     ]
-   }
-
-Two exceptions are the two arrays of "finishers" / "validators" (``property
-collections``) and the ``renderables``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-propertycollectionproperties:
-
-Remove property collection properties
-'''''''''''''''''''''''''''''''''''''
-
-In principle, the same applies here as for :ref:`get property collection properties<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties>`.
-
-Delete the property ``options.minimum`` of the validator ``StringLength``:
-
-.. code-block:: javascript
-
-   var formElement = getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name');
-   var propertyPath = getFormEditorApp().buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
-   formElement.unset(propertyPath);
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-renderables:
-
-Remove renderables
-''''''''''''''''''
-
-To delete a ``FormElement model``, the corresponding API method
-``getFormEditorApp().removeFormElement()`` should be used.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-on:
-
-Method: on()
-++++++++++++
-
-Any number of :ref:`Publisher/Subscriber<concepts-formeditor-basicjavascriptconcepts-events>`
-events can be assigned to any property path of a ``FormElement model``. Each
-``set()`` operation on this property path will then call these events. By
-default, EXT:form registers the event :ref:`core/formElement/somePropertyChanged<apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged>`
-for each property path.
-
-Example:
-
-.. code-block:: javascript
-
-   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').on('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
-   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
-   // now, the event 'my/custom/event' will be published
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-off:
-
-Method: off()
-+++++++++++++
-
-Any event registered via :ref:`on()<apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-on>`
-can be removed with off().
-
-Example:
-
-.. code-block:: javascript
-
-   getFormEditorApp().getFormElementByIdentifierPath('example-form/page-1/name').off('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-getobjectdata:
-
-Method: getObjectData()
-+++++++++++++++++++++++
-
-All ``FormElement model`` properties are private and cannot be manipulated
-directly from the outside. They can only be accessed via ``set()`` or
-``get()``. This method is used internally to obtain all data of a ``FormElement
-model`` in object form so that they can be used in, for example, Ajax requests.
-``getObjectData()`` returns a dereferenced object of the ``FormElement model``
-with all internal data, thus allowing read access to all data set via
-``set()``.
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-tostring:
-
-Method: toString()
-++++++++++++++++++
-
-A method that was implemented for debugging purposes. Returns the object data
-supplied by ``getObjectData()`` in string form.
-
-.. code-block:: javascript
-
-   console.log(formElement.toString());
-
-
-.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-clone:
-
-Method: clone()
-+++++++++++++++
-
-If necessary, a form element can be cloned. Returns a dereferenced clone of the
-original ``FormElement model``.
-
-
-.. code-block:: javascript
-
-   var dolly = formElement.clone();
diff --git a/typo3/sysext/form/Documentation/I/Index.rst b/typo3/sysext/form/Documentation/I/Index.rst
index 14b5e30dc9ae..1521ef789e56 100644
--- a/typo3/sysext/form/Documentation/I/Index.rst
+++ b/typo3/sysext/form/Documentation/I/Index.rst
@@ -12,5 +12,4 @@ For Integrators
 
    Concepts/Index
    Config/Index
-   ApiReference/Index
    FAQ/Index
diff --git a/typo3/sysext/form/Documentation/Index.rst b/typo3/sysext/form/Documentation/Index.rst
index 31e5e24ceea3..2bfe01e0f424 100644
--- a/typo3/sysext/form/Documentation/Index.rst
+++ b/typo3/sysext/form/Documentation/Index.rst
@@ -48,6 +48,7 @@ a GNU/GPL CMS/Framework available from https://typo3.org/
    Introduction/Index
    QuickStartForEditors/Index
    QuickStartForIntegrators/Index
+   D/Index
    I/Index
    E/Index
    Targets
-- 
GitLab