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¶m2=value2' + ... + + +Usage through code:: + + $formDefinition->createFinisher('Redirect', [ + 'pageUid' => 1, + 'additionalParameters' => 'param1=value1¶m2=value2', + ]); + +or create manually (not preferred):: + + $redirectFinisher = GeneralUtility::makeInstance(RedirectFinisher::class); + $redirectFinisher->setOptions([ + 'pageUid' => 1, + 'additionalParameters' => 'param1=value1¶m2=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¶m2=value2' - ... - - -Usage through code:: - - $formDefinition->createFinisher('Redirect', [ - 'pageUid' => 1, - 'additionalParameters' => 'param1=value1¶m2=value2', - ]); - -or create manually (not preferred):: - - $redirectFinisher = GeneralUtility::makeInstance(RedirectFinisher::class); - $redirectFinisher->setOptions([ - 'pageUid' => 1, - 'additionalParameters' => 'param1=value1¶m2=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