1 .. include:: ../Includes.txt
10 This chapter is a complete reference of the API of the form framework. It
11 mainly addresses your concerns as a developer.
14 .. _apireference-frontendrendering:
20 .. _apireference-frontendrendering-fluidformrenderer:
22 TYPO3\\CMS\\Form\\Domain\\Renderer\\FluidFormRenderer
23 -----------------------------------------------------
26 .. _apireference-frontendrendering-fluidformrenderer-options:
31 The ``FluidFormRenderer`` uses some rendering options which are of particular importance,
32 as they determine how the form field is resolved to a path in the file system.
34 All rendering options are retrieved from the ``FormDefinition``, using the ``TYPO3\CMS\Form\Domain\Model\FormDefinition::getRenderingOptions()`` method.
37 .. _apireference-frontendrendering-fluidformrenderer-options-templaterootpaths:
42 Used to define several paths for templates, which will be tried in reversed order (the paths are searched from bottom to top).
43 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.
44 Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
48 templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Templates/
49 $renderable->getType() == 'Form'
50 Expected template file: EXT:form/Resources/Private/Frontend/Templates/Form.html
52 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``.
61 formElementsDefinition:
65 10: 'EXT:form/Resources/Private/Frontend/Templates/'
68 .. _apireference-frontendrendering-fluidformrenderer-options-layoutrootpaths:
73 Used to define several paths for layouts, which will be tried in reversed order (the paths are searched from bottom to top).
74 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.
83 formElementsDefinition:
87 10: 'EXT:form/Resources/Private/Frontend/Layouts/'
90 .. _apireference-frontendrendering-fluidformrenderer-options-partialrootpaths:
95 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.
96 The keys of the array define the order.
98 Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
102 templateRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
103 $renderable->getType() == 'Text'
104 Expected template file: EXT:form/Resources/Private/Frontend/Partials/Text.html
106 There is a setting available to set a custom partial name. Please read the section :ref:`templateName<apireference-frontendrendering-fluidformrenderer-options-templatename>`.
115 formElementsDefinition:
119 10: 'EXT:form/Resources/Private/Frontend/Partials/'
122 .. _apireference-frontendrendering-fluidformrenderer-options-templatename:
127 By default, the renderable type will be taken as the name for the partial.
131 partialRootPaths.10 = EXT:form/Resources/Private/Frontend/Partials/
132 $renderable->getType() == 'Text'
133 Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
135 Set ``templateName`` to define a custom name which should be used instead.
139 $renderable->getTemplateName() == 'Text'
140 $renderable->getType() = Foo
141 Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
150 formElementsDefinition:
156 .. _apireference-frontendrendering-renderviewHelper:
161 .. _apireference-frontendrendering-renderviewHelper-arguments:
166 .. _apireference-frontendrendering-renderviewHelper-factoryclass:
171 A class name of a ``FormFactory``.
172 This factory is used to create the ``TYPO3\CMS\Form\Domain\Model\FormDefinition`` which is the ``form definition`` Domain Model.
173 If no ``factoryClass`` argument is passed, the factory supplied by EXT:form ``TYPO3\CMS\Form\ Domain\Factory\ArrayFormFactory`` is used.
174 Another factory class is required if the form is to be generated programmatically.
175 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.
176 This then renders the form.
180 <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
183 .. _apireference-frontendrendering-renderviewHelper-persistenceidentifier:
185 persistenceIdentifier
186 +++++++++++++++++++++
188 The ``form definition`` to be found under ``persistenceIdentifier``.
189 The PersistenceManager now loads the ``form definition`` which is found under ``persistenceIdentifier`` and passes this configuration to the ``factoryClass``.
190 In this case, the ``factoryClass`` will be given an empty configuration array (if ``overrideConfiguration`` is not specified).
194 <formvh:render persistenceIdentifier="EXT:my_site_package/Resources/Private/Forms/SimpleContactForm.yaml" />
197 .. _apireference-frontendrendering-renderviewHelper-overrideconfiguration:
199 overrideConfiguration
200 +++++++++++++++++++++
202 A configuration to be superimposed can be entered here.
203 If a ``persistenceIdentifier`` is specified, the ``form definition`` which is found under ``persistenceIdentifier`` is loaded.
204 This configuration is then superimposed with ``overrideConfiguration``. This configuration is then passed to the ``factoryClass``.
205 If no ``persistenceIdentifier`` is specified, ``overrideConfiguration`` is passed directly to the ``factoryClass``.
206 This way a configuration can be given to a ``factoryClass`` implementation.
209 .. _apireference-frontendrendering-renderviewHelper-prototypename:
214 The name of the prototype, on which basis the ``factoryClass`` should create the form.
215 If nothing is specified, the configuration (``form definition`` or ``overrideConfiguration``) is searched for the prototy name.
216 If no specification exists, the standard prototype ``standard`` is used.
220 .. _apireference-frontendrendering-programmatically:
222 Build forms programmatically
223 ----------------------------
225 Implement a ``FormFactory`` and build the form.
230 declare(strict_types=1);
231 namespace VENDOR\MySitePackage\Domain\Factory;
233 use TYPO3\CMS\Core\Utility\GeneralUtility;
234 use TYPO3\CMS\Extbase\Object\ObjectManager;
235 use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
236 use TYPO3\CMS\Extbase\Validation\Validator\StringLengthValidator;
237 use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
238 use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
239 use TYPO3\CMS\Form\Domain\Model\FormDefinition;
241 class CustomFormFactory extends AbstractFormFactory
245 * Build a FormDefinition.
246 * This example build a FormDefinition manually,
247 * so $configuration and $prototypeName are unused.
249 * @param array $configuration
250 * @param string $prototypeName
251 * @return FormDefinition
253 public function build(array $configuration, string $prototypeName = null): FormDefinition
255 $prototypeName = 'standard';
256 $configurationService = GeneralUtility::makeInstance(ObjectManager::class)->get(ConfigurationService::class);
257 $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
259 $form = GeneralUtility::makeInstance(ObjectManager::class)->get(FormDefinition::class, 'MyCustomForm', $prototypeConfiguration);
260 $form->setRenderingOption('controllerAction', 'index');
262 $page1 = $form->createPage('page1');
263 $name = $page1->createElement('name', 'Text');
264 $name->setLabel('Name');
265 $name->addValidator(GeneralUtility::makeInstance(ObjectManager::class)->get(NotEmptyValidator::class));
267 $page2 = $form->createPage('page2');
268 $message = $page2->createElement('message', 'Textarea');
269 $message->setLabel('Message');
270 $message->addValidator(GeneralUtility::makeInstance(ObjectManager::class)->get(StringLengthValidator::class, ['minimum' => 5, 'maximum' => 20]));
272 $form->createFinisher('EmailToSender', [
273 'subject' => 'Hello',
274 'recipientAddress' => 'foo@example.com',
275 'senderAddress' => 'bar@example.com',
278 $this->triggerFormBuildingFinished($form);
284 Use this form within your fluid template.
288 <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
291 .. _apireference-frontendrendering-programmatically-commonapimethods:
297 .. _apireference-frontendrendering-programmatically-commonapimethods-createpage:
299 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createPage()
300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
302 Create a page with the given $identifier and attach this page to the form.
304 - Create Page object based on the given $typeName
305 - set defaults inside the Page object
306 - attach Page object to this form
307 - return the newly created Page object
313 public function createPage(string $identifier, string $typeName = 'Page'): Page;
316 .. _apireference-frontendrendering-programmatically-commonapimethods-createfinisher:
318 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createFinisher()
319 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
321 Create a finisher with the given $identifier and given $options and attach this finisher to the form.
327 public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
330 .. _apireference-frontendrendering-programmatically-commonapimethods-page-createelement:
332 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page::createElement()
333 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
335 Create a form element with the given $identifier and attach it to the page.
337 - Create Form Element object based on the given $typeName
338 - set defaults inside the Form Element (based on the parent form's field defaults)
339 - attach Form Element to the Page
340 - return the newly created Form Element object
346 public function createElement(string $identifier, string $typeName): FormElementInterface;
349 .. _apireference-frontendrendering-programmatically-commonapimethods-section-createelement:
351 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section::createElement()
352 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
354 Create a form element with the given $identifier and attach it to the section.
356 - Create Form Element object based on the given $typeName
357 - set defaults inside the Form Element (based on the parent form's field defaults)
358 - attach Form Element to the Section
359 - return the newly created Form Element object
365 public function createElement(string $identifier, string $typeName): FormElementInterface;
368 .. _apireference-frontendrendering-programmatically-commonapimethods-abstractrenderable-createvalidator:
370 TYPO3\\CMS\\Form\\Domain\\Model\\Renderable\\AbstractFormElement::createValidator()
371 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
373 Create a validator for the element.
376 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
377 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
378 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
379 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
385 public function createValidator(string $validatorIdentifier, array $options = []);
388 .. _apireference-frontendrendering-programmatically-commonapimethods-initializeformelement:
390 initializeFormElement()
391 +++++++++++++++++++++++
393 Will be called as soon as the element is added to a form.
396 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
397 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
398 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
399 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
400 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
406 public function initializeFormElement();
409 You can use this method to prefill form element data for example from database tables.
410 All the classes you can see above extends from the ``TYPO3\CMS\Form\Domain\Model\FormElement\AbstractFormElement``.
411 ``AbstractFormElement`` implements this method like this
415 public function initializeFormElement()
418 isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
419 && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
421 foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'] as $className) {
422 $hookObj = GeneralUtility::makeInstance($className);
423 if (method_exists($hookObj, 'initializeFormElement')) {
424 $hookObj->initializeFormElement(
432 If you extend you custom implementation from ``AbstractFormElement`` (and you should do this),
433 it enables you to override the 'initializeFormElement' method within your custom implementation class.
434 If you do not call the parents 'initializeFormElement' then no hook will be thrown.
436 If your use case for a custom form element implementation means that you only want to initialize you form element
437 programmatically (e.g to get databasedata) and no other special things are to do, you might prefer the hook.
438 You only need a class which connects to this hook. Then detect the form element you wish to initialize.
441 .. _apireference-frontendrendering-programmatically-apimethods:
447 .. _apireference-frontendrendering-programmatically-apimethods-formruntime:
449 TYPO3\\CMS\\Form\\Domain\\Model\\FormRuntime
450 ++++++++++++++++++++++++++++++++++++++++++++
453 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-overridecurrentpage:
455 overrideCurrentPage()
456 '''''''''''''''''''''
458 Override the current page taken from the request, rendering the page with index $pageIndex instead.
459 This is typically not needed in production code.
460 You might prefer the hook :ref:`afterInitializeCurrentPage <apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage>`
466 public function overrideCurrentPage(int $pageIndex);
472 $form = $formDefinition->bind($this->request, $this->response);
473 $form->overrideCurrentPage($pageIndex);
476 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-render:
487 public function render();
490 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getidentifier:
491 .. include:: RootRenderableInterface/getIdentifier.rst
493 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrequest:
498 Get the request this object is bound to.
499 This is mostly relevant inside Finishers, where you f.e. want to redirect the user to another page.
505 public function getRequest(): Request;
508 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getresponse:
513 Get the response this object is bound to.
514 This is mostly relevant inside Finishers, where you f.e. want to set response headers or output content.
520 public function getResponse(): Response;
523 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getcurrentpage:
528 Returns the currently selected page.
534 public function getCurrentPage(): Page;
537 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpreviouspage:
542 Returns the previous page of the currently selected one or NULL if there is no previous page.
548 public function getPreviousPage();
551 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getnextpage:
556 Returns the next page of the currently selected one or NULL if there is no next page.
562 public function getNextPage();
565 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettype:
566 .. include:: RootRenderableInterface/getType.rst
569 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getelementvalue:
574 Returns the value of the specified element.
580 public function getElementValue(string $identifier);
583 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpages:
588 Return the form's pages in the correct order.
594 public function getPages(): array;
597 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrenderingoptions:
598 .. include:: RootRenderableInterface/getRenderingOptions.rst
600 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrendererclassname:
601 .. include:: RootRenderableInterface/getRendererClassName.rst
604 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getlabel:
605 .. include:: RootRenderableInterface/getLabel.rst
607 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettemplatename:
608 .. include:: RenderableInterface/getTemplateName.rst
610 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getformdefinition:
615 Get the underlying form definition from the runtime.
621 public function getFormDefinition(): FormDefinition;
624 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition:
626 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition
627 +++++++++++++++++++++++++++++++++++++++++++++++
629 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addpage:
634 Add a new page at the end of the form.
635 Instead of this method, you should use ``createPage`` instead.
641 public function addPage(Page $page);
644 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createpage:
649 Create a page with the given $identifier and attach this page to the form.
651 - Create Page object based on the given $typeName
652 - set defaults inside the Page object
653 - attach Page object to this form
654 - return the newly created Page object
660 public function createPage(string $identifier, string $typeName = 'Page'): Page;
663 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpages:
668 Return the form's pages in the correct order.
674 public function getPages(): array;
677 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-haspagewithindex:
682 Check whether a page with the given $index exists.
688 public function hasPageWithIndex(int $index): bool;
691 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpagebyindex:
696 Get the page with the passed index. The first page has index zero.
697 If page at $index does not exist, an exception is thrown.
703 public function getPageByIndex(int $index);
706 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addfinisher:
711 Adds the specified finisher to the form.
712 Instead of this method, you should use ``createFinisher`` instead.
718 public function addFinisher(FinisherInterface $finisher);
721 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createfinisher:
726 Create a finisher with the given $identifier and given $options and attach this finisher to the form.
732 public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
734 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getfinishers:
739 Gets all finishers of the form.
745 public function getFinishers(): array;
748 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getelementbyidentifier:
750 getElementByIdentifier()
751 ''''''''''''''''''''''''
753 Get a form element by its identifier.
754 If identifier does not exist, returns NULL.
760 public function getElementByIdentifier(string $elementIdentifier);
763 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-movepageafter:
768 Move $pageToMove after $referencePage.
774 public function movePageAfter(Page $pageToMove, Page $referencePage);
777 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-removepage:
782 Remove $pageToRemove from the form.
788 public function removePage(Page $pageToRemove);
791 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-bind:
796 Bind the current request and response to this form instance, effectively creating a new "instance" of the Form.
802 public function bind(Request $request, Response $response): FormRuntime;
805 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getprocessingrule:
810 Get the processing rule which contains information for property mappings and validations.
816 public function getProcessingRule(string $propertyPath): ProcessingRule;
819 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettype:
820 .. include:: RootRenderableInterface/getType.rst
822 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getidentifier:
823 .. include:: RootRenderableInterface/getIdentifier.rst
825 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setidentifier:
826 .. include:: AbstractRenderable/setIdentifier.rst
828 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setoptions:
829 .. include:: AbstractRenderable/setOptions.rst
831 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addvalidator:
832 .. include:: FormElementInterface/addValidator.rst
834 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setdatatype:
835 .. include:: FormElementInterface/setDataType.rst
837 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrendererclassname:
838 .. include:: RootRenderableInterface/getRendererClassName.rst
840 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrendererclassname:
842 setRendererClassName()
843 ''''''''''''''''''''''
845 Set the renderer class name.
851 public function setRendererClassName(string $rendererClassName);
854 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrenderingoptions:
855 .. include:: RootRenderableInterface/getRenderingOptions.rst
857 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrenderingoption:
858 .. include:: FormElementInterface/setRenderingOption.rst
860 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getparentrenderable:
861 .. include:: RenderableInterface/getParentRenderable.rst
863 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setparentrenderable:
864 .. include:: RenderableInterface/setParentRenderable.rst
866 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrootform:
867 .. include:: AbstractRenderable/getRootForm.rst
869 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getlabel:
870 .. include:: RootRenderableInterface/getLabel.rst
872 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setlabel:
873 .. include:: AbstractRenderable/setLabel.rst
875 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettemplatename:
876 .. include:: RenderableInterface/getTemplateName.rst
879 .. _apireference-frontendrendering-programmatically-apimethods-page:
881 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page
882 +++++++++++++++++++++++++++++++++++++++++++++++++++
884 .. _apireference-frontendrendering-programmatically-apimethods-page-getelements:
885 .. include:: AbstractSection/getElements.rst
887 .. _apireference-frontendrendering-programmatically-apimethods-page-getelementsrecursively:
888 .. include:: AbstractSection/getElementsRecursively.rst
890 .. _apireference-frontendrendering-programmatically-apimethods-page-addelement:
891 .. include:: AbstractSection/addElement.rst
893 .. _apireference-frontendrendering-programmatically-apimethods-page-createelement:
898 Create a form element with the given $identifier and attach it to the page.
900 - Create Form Element object based on the given $typeName
901 - set defaults inside the Form Element (based on the parent form's field defaults)
902 - attach Form Element to the Page
903 - return the newly created Form Element object
909 public function createElement(string $identifier, string $typeName): FormElementInterface;
912 .. _apireference-frontendrendering-programmatically-apimethods-page-moveelementbefore:
913 .. include:: AbstractSection/moveElementBefore.rst
915 .. _apireference-frontendrendering-programmatically-apimethods-page-moveelementafter:
916 .. include:: AbstractSection/moveElementAfter.rst
918 .. _apireference-frontendrendering-programmatically-apimethods-page-removeelement:
919 .. include:: AbstractSection/removeElement.rst
921 .. _apireference-frontendrendering-programmatically-apimethods-page-gettype:
922 .. include:: RootRenderableInterface/getType.rst
924 .. _apireference-frontendrendering-programmatically-apimethods-page-getidentifier:
925 .. include:: RootRenderableInterface/getIdentifier.rst
927 .. _apireference-frontendrendering-programmatically-apimethods-page-setidentifier:
928 .. include:: AbstractRenderable/setIdentifier.rst
930 .. _apireference-frontendrendering-programmatically-apimethods-page-setoptions:
931 .. include:: AbstractRenderable/setOptions.rst
933 .. _apireference-frontendrendering-programmatically-apimethods-page-addvalidator:
934 .. include:: FormElementInterface/addValidator.rst
936 .. _apireference-frontendrendering-programmatically-apimethods-page-createvalidator:
937 .. include:: FormElementInterface/createValidator.rst
939 .. _apireference-frontendrendering-programmatically-apimethods-page-setdatatype:
940 .. include:: FormElementInterface/setDataType.rst
942 .. _apireference-frontendrendering-programmatically-apimethods-page-getrendererclassname:
943 .. include:: RootRenderableInterface/getRendererClassName.rst
945 .. _apireference-frontendrendering-programmatically-apimethods-page-getrenderingoptions:
946 .. include:: RootRenderableInterface/getRenderingOptions.rst
948 .. _apireference-frontendrendering-programmatically-apimethods-page-setrenderingoption:
949 .. include:: FormElementInterface/setRenderingOption.rst
951 .. _apireference-frontendrendering-programmatically-apimethods-page-getparentrenderable:
952 .. include:: RenderableInterface/getParentRenderable.rst
954 .. _apireference-frontendrendering-programmatically-apimethods-page-setparentrenderable:
955 .. include:: RenderableInterface/setParentRenderable.rst
957 .. _apireference-frontendrendering-programmatically-apimethods-page-getrootform:
958 .. include:: AbstractRenderable/getRootForm.rst
960 .. _apireference-frontendrendering-programmatically-apimethods-page-getlabel:
961 .. include:: RootRenderableInterface/getLabel.rst
963 .. _apireference-frontendrendering-programmatically-apimethods-page-setlabel:
964 .. include:: AbstractRenderable/setLabel.rst
966 .. _apireference-frontendrendering-programmatically-apimethods-page-gettemplatename:
967 .. include:: RenderableInterface/getTemplateName.rst
970 .. _apireference-frontendrendering-programmatically-apimethods-section:
972 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
973 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
975 .. _apireference-frontendrendering-programmatically-apimethods-section-initializeformelement:
976 .. include:: FormElementInterface/initializeFormElement.rst
978 .. _apireference-frontendrendering-programmatically-apimethods-section-getuniqueidentifier:
979 .. include:: FormElementInterface/getUniqueIdentifier.rst
981 .. _apireference-frontendrendering-programmatically-apimethods-section-setproperty:
982 .. include:: FormElementInterface/setProperty.rst
984 .. _apireference-frontendrendering-programmatically-apimethods-section-getproperties:
985 .. include:: FormElementInterface/getProperties.rst
987 .. _apireference-frontendrendering-programmatically-apimethods-section-isrequired:
988 .. include:: FormElementInterface/isRequired.rst
990 .. _apireference-frontendrendering-programmatically-apimethods-section-getelements:
991 .. include:: AbstractSection/getElements.rst
993 .. _apireference-frontendrendering-programmatically-apimethods-section-getelementsrecursively:
994 .. include:: AbstractSection/getElementsRecursively.rst
996 .. _apireference-frontendrendering-programmatically-apimethods-section-addelement:
997 .. include:: AbstractSection/addElement.rst
999 .. _apireference-frontendrendering-programmatically-apimethods-section-createelement:
1004 Create a form element with the given $identifier and attach it to the section.
1006 - Create Form Element object based on the given $typeName
1007 - set defaults inside the Form Element (based on the parent form's field defaults)
1008 - attach Form Element to the Section
1009 - return the newly created Form Element object
1015 public function createElement(string $identifier, string $typeName): FormElementInterface;
1018 .. _apireference-frontendrendering-programmatically-apimethods-section-moveelementbefore:
1019 .. include:: AbstractSection/moveElementBefore.rst
1021 .. _apireference-frontendrendering-programmatically-apimethods-section-moveelementafter:
1022 .. include:: AbstractSection/moveElementAfter.rst
1024 .. _apireference-frontendrendering-programmatically-apimethods-section-removeelement:
1025 .. include:: AbstractSection/removeElement.rst
1027 .. _apireference-frontendrendering-programmatically-apimethods-section-gettype:
1028 .. include:: RootRenderableInterface/getType.rst
1030 .. _apireference-frontendrendering-programmatically-apimethods-section-getidentifier:
1031 .. include:: RootRenderableInterface/getIdentifier.rst
1033 .. _apireference-frontendrendering-programmatically-apimethods-section-setidentifier:
1034 .. include:: AbstractRenderable/setIdentifier.rst
1036 .. _apireference-frontendrendering-programmatically-apimethods-section-setoptions:
1037 .. include:: AbstractRenderable/setOptions.rst
1039 .. _apireference-frontendrendering-programmatically-apimethods-section-addvalidator:
1040 .. include:: FormElementInterface/addValidator.rst
1042 .. _apireference-frontendrendering-programmatically-apimethods-section-createvalidator:
1043 .. include:: FormElementInterface/createValidator.rst
1045 .. _apireference-frontendrendering-programmatically-apimethods-section-setdatatype:
1046 .. include:: FormElementInterface/setDataType.rst
1048 .. _apireference-frontendrendering-programmatically-apimethods-section-getrendererclassname:
1049 .. include:: RootRenderableInterface/getRendererClassName.rst
1051 .. _apireference-frontendrendering-programmatically-apimethods-section-getrenderingoptions:
1052 .. include:: RootRenderableInterface/getRenderingOptions.rst
1054 .. _apireference-frontendrendering-programmatically-apimethods-section-setrenderingoption:
1055 .. include:: FormElementInterface/setRenderingOption.rst
1057 .. _apireference-frontendrendering-programmatically-apimethods-section-getparentrenderable:
1058 .. include:: RenderableInterface/getParentRenderable.rst
1060 .. _apireference-frontendrendering-programmatically-apimethods-section-setparentrenderable:
1061 .. include:: RenderableInterface/setParentRenderable.rst
1063 .. _apireference-frontendrendering-programmatically-apimethods-section-getrootform:
1064 .. include:: AbstractRenderable/getRootForm.rst
1066 .. _apireference-frontendrendering-programmatically-apimethods-section-getlabel:
1067 .. include:: RootRenderableInterface/getLabel.rst
1069 .. _apireference-frontendrendering-programmatically-apimethods-section-setlabel:
1070 .. include:: AbstractRenderable/setLabel.rst
1072 .. _apireference-frontendrendering-programmatically-apimethods-section-gettemplatename:
1073 .. include:: RenderableInterface/getTemplateName.rst
1076 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement:
1078 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AbstractFormElement
1079 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1081 The following classes extends from ``AbstractFormElement`` and therefore contain the following API methods.
1083 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
1084 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
1085 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
1086 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
1089 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-initializeformelement:
1090 .. include:: FormElementInterface/initializeFormElement.rst
1092 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getuniqueidentifier:
1093 .. include:: FormElementInterface/getUniqueIdentifier.rst
1095 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getdefaultvalue:
1096 .. include:: FormElementInterface/getDefaultValue.rst
1098 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdefaultvalue:
1099 .. include:: FormElementInterface/setDefaultValue.rst
1101 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setproperty:
1102 .. include:: FormElementInterface/setProperty.rst
1104 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getproperties:
1105 .. include:: FormElementInterface/getProperties.rst
1107 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-isrequired:
1108 .. include:: FormElementInterface/isRequired.rst
1110 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettype:
1111 .. include:: RootRenderableInterface/getType.rst
1113 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getidentifier:
1114 .. include:: RootRenderableInterface/getIdentifier.rst
1116 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setidentifier:
1117 .. include:: AbstractRenderable/setIdentifier.rst
1119 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setoptions:
1120 .. include:: AbstractRenderable/setOptions.rst
1122 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-addvalidator:
1123 .. include:: FormElementInterface/addValidator.rst
1125 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-createvalidator:
1126 .. include:: FormElementInterface/createValidator.rst
1128 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdatatype:
1129 .. include:: FormElementInterface/setDataType.rst
1131 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrendererclassname:
1132 .. include:: RootRenderableInterface/getRendererClassName.rst
1134 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrenderingoptions:
1135 .. include:: RootRenderableInterface/getRenderingOptions.rst
1137 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setrenderingoption:
1138 .. include:: FormElementInterface/setRenderingOption.rst
1140 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getparentrenderable:
1141 .. include:: RenderableInterface/getParentRenderable.rst
1143 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setparentrenderable:
1144 .. include:: RenderableInterface/setParentRenderable.rst
1146 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrootform:
1147 .. include:: AbstractRenderable/getRootForm.rst
1149 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getlabel:
1150 .. include:: RootRenderableInterface/getLabel.rst
1152 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setlabel:
1153 .. include:: AbstractRenderable/setLabel.rst
1155 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettemplatename:
1156 .. include:: RenderableInterface/getTemplateName.rst
1159 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher:
1161 TYPO3\\CMS\\Form\\Domain\\Finishers\\AbstractFinisher
1162 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1164 The following classes extends from ``AbstractFinisher`` and therefore contain the following API methods.
1166 - TYPO3\\CMS\\Form\\Domain\\Finishers\\ClosureFinisher
1167 - TYPO3\\CMS\\Form\\Domain\\Finishers\\ConfirmationFinisher
1168 - TYPO3\\CMS\\Form\\Domain\\Finishers\\DeleteUploadsFinisher
1169 - TYPO3\\CMS\\Form\\Domain\\Finishers\\EmailFinisher
1170 - TYPO3\\CMS\\Form\\Domain\\Finishers\\FlashMessageFinisher
1171 - TYPO3\\CMS\\Form\\Domain\\Finishers\\RedirectFinisher
1172 - TYPO3\\CMS\\Form\\Domain\\Finishers\\SaveToDatabaseFinisher
1175 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-execute:
1180 Executes the finisher. ``AbstractFinisher::execute()`` call ``$this->executeInternal()`` at the end. Own finisher
1181 implementations which extends from ``AbstractFinisher:`` must start their own logic within ``executeInternal()``.
1187 public function execute(FinisherContext $finisherContext);
1190 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoptions:
1195 Set the finisher options. Instead of directly accessing them, you should rather use ``parseOption()``.
1201 public function setOptions(array $options);
1204 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoption:
1209 Sets a single finisher option.
1215 public function setOption(string $optionName, $optionValue);
1218 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-parseoption:
1223 Please read :ref:`Accessing finisher options<concepts-frontendrendering-codecomponents-customfinisherimplementations-accessingoptions>`
1229 protected function parseOption(string $optionName);
1232 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext:
1234 TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherContext
1235 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1237 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-cancel:
1242 Cancels the finisher invocation after the current finisher.
1248 public function cancel();
1251 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformruntime:
1256 The Form Runtime that is associated with the current finisher.
1262 public function getFormRuntime(): FormRuntime;
1265 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformvalues:
1270 The values of the submitted form (after validation and property mapping).
1276 public function getFormValues(): array;
1279 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getcontrollercontext:
1281 getControllerContext()
1282 ''''''''''''''''''''''
1284 Returns the current ControllerContext.
1290 public function getControllerContext(): ControllerContext;
1293 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getfinishervariableprovider:
1295 getFinisherVariableProvider()
1296 '''''''''''''''''''''''''''''
1298 Returns the current FinisherVariableProvider.
1304 public function getFinisherVariableProvider(): FinisherVariableProvider;
1307 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider:
1309 TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherVariableProvider
1310 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1312 Please read :ref:`Share data between finishers<concepts-frontendrendering-codecomponents-customfinisherimplementations-finishercontext-sharedatabetweenfinishers>`
1314 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-add:
1319 Add a variable to the finisher variable provider.
1320 In case the value is already inside, it is silently overridden.
1326 public function add(string $finisherIdentifier, string $key, $value);
1329 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-get:
1334 Gets a variable from the finisher variable provider.
1340 public function get(string $finisherIdentifier, string $key, $default = null);
1343 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-exists:
1348 Determine whether there is a variable stored for the given key.
1354 public function exists($finisherIdentifier, $key): bool;
1357 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-remove:
1362 Remove a value from the finisher variable provider.
1368 public function remove(string $finisherIdentifier, string $key);
1371 .. _apireference-frontendrendering-programmatically-apimethods-configurationservice:
1373 TYPO3\\CMS\\Form\\Domain\\Configuration\\ConfigurationService
1374 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1376 .. _apireference-frontendrendering-programmatically-apimethods-configurationservice-getprototypeconfiguration:
1378 getPrototypeConfiguration()
1379 '''''''''''''''''''''''''''
1381 Get the configuration for a given $prototypeName
1387 public function getPrototypeConfiguration(string $prototypeName): array;
1390 .. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory:
1392 TYPO3\\CMS\\Form\\Domain\\Factory\\AbstractFormFactory
1393 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1395 .. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory-triggerformbuildingfinished:
1397 triggerFormBuildingFinished()
1398 '''''''''''''''''''''''''''''
1400 Helper to be called by every ``FormFactory`` which extends from ``AbstractFormFactory`` after
1401 everything has been built to call the "afterBuildingFinished" hook on all form elements.
1407 protected function triggerFormBuildingFinished(FormDefinition $form);
1410 .. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface:
1412 TYPO3\\CMS\\Form\\Domain\\Factory\\FormFactoryInterface
1413 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1415 .. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface-build:
1420 Build a form definition, depending on some configuration.
1426 public function build(array $configuration, string $prototypeName = null): FormDefinition;
1429 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface:
1431 TYPO3\\CMS\\Form\\Domain\\Renderer\\RendererInterface
1432 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1434 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setcontrollercontext:
1436 setControllerContext()
1437 ''''''''''''''''''''''
1439 Set the controller context which should be used
1443 public function setControllerContext(ControllerContext $controllerContext);
1446 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-render:
1451 Renders the FormDefinition. This method is expected to call the ``beforeRendering`` hook on each form element.
1455 public function render(): string;
1458 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setformruntime:
1463 Set the current ``FormRuntime``.
1467 public function setFormRuntime(FormRuntime $formRuntime);
1470 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-getformruntime:
1475 Get the current ``FormRuntime``.
1479 public function getFormRuntime(): FormRuntime;
1483 .. _apireference-frontendrendering-runtimemanipulation:
1485 Runtime manipulation
1486 --------------------
1488 .. _apireference-frontendrendering-runtimemanipulation-hooks:
1494 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement:
1496 initializeFormElement
1497 +++++++++++++++++++++
1499 You can connect to the hook and initialize a form elements without defining a custom implementaion to access the element's ``initializeFormElement`` method.
1500 You only need a class which connects to this hook. Then detect the form element you wish to initialize.
1501 You can use this hook to prefill form element data for example from database tables.
1503 This hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::createElement()`` and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::createElement()``.
1504 That means the hook will **not** be triggered for ``Pages``.
1505 At this point you don't have access to submitted form element values.
1508 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-connect:
1515 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
1516 = \VENDOR\YourNamespace\YourClass::class;
1519 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-use:
1527 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1530 public function initializeFormElement(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1532 if ($renderable->getUniqueIdentifier() === 'contactForm-text-1') {
1533 $renderable->setDefaultValue('foo');
1538 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable:
1540 beforeRemoveFromParentRenderable
1541 ++++++++++++++++++++++++++++++++
1543 This hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormDefinition::removePage()``, ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::removeElement()``
1544 and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::removeElement()``
1547 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-connect:
1554 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'][<useATimestampAsKeyPlease>]
1555 = \VENDOR\YourNamespace\YourClass::class;
1558 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-use:
1566 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1569 public function beforeRemoveFromParentRenderable(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1574 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished:
1576 afterBuildingFinished
1577 +++++++++++++++++++++
1579 This hook is called for each form element after the class ``TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory``
1580 has built the entire form. This hook is triggered just before the
1581 ``FormRuntime`` object is generated. At this point, no run-time information
1582 (e.g. assigned form values) is yet available. It can, for example, be used to
1583 generate new form elements within complex forms. The ``ArrayFormFactory`` is
1584 used by EXT:form via the ``RenderViewHelper`` to render forms using a ``form
1585 definition`` YAML file. Each form factory implementation must deal with the
1586 calling of this hook themselves. EXT:form itself uses this hook to initialize
1587 the property-mapper configuration for ``FileUpload`` elements.
1589 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-connect:
1596 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterBuildingFinished'][<useATimestampAsKeyPlease>]
1597 = \VENDOR\YourNamespace\YourClass::class;
1600 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-use:
1608 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1611 public function afterBuildingFinished(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1616 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage:
1618 afterInitializeCurrentPage
1619 ++++++++++++++++++++++++++
1621 EXT:form automatically detects the page that should be shown and allow users
1622 only to jump to the directly following (or previous) pages. This hook enables
1623 you to implement a custom behavior, for example pages that are shown only when
1624 other form elements have specific values.
1627 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-connect:
1634 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterInitializeCurrentPage'][<useATimestampAsKeyPlease>]
1635 = \VENDOR\YourNamespace\YourClass::class;
1638 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-use:
1646 * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1647 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage
1648 * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage
1649 * @param mixed $elementValue submitted value of the element *before post processing*
1650 * @return \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
1652 public function afterInitializeCurrentPage(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage, \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage = null, array $requestArguments = []): CompositeRenderableInterface
1654 return $currentPage;
1658 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit:
1663 You can use it for example for dynamic validations which depends on other submitted form element values.
1664 This hook is invoked by the ``FormRuntime`` for each form element **before** values are property mapped, validated and pushed within the FormRuntime's ``FormState``.
1665 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
1666 the submitted form element values from the first page. In this case you can access the submitted raw data through ``$requestArguments``.
1667 EXT:form itself uses this hook to dynamically add validation errors for ``AdvancedPassword`` form elements.
1670 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-connect:
1677 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterSubmit'][<useATimestampAsKeyPlease>]
1678 = \VENDOR\YourNamespace\YourClass::class;
1681 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-use:
1689 * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1690 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1691 * @param mixed $elementValue submitted value of the element *before post processing*
1692 * @param array $requestArguments submitted raw request values
1695 public function afterSubmit(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable, $elementValue, array $requestArguments = [])
1697 return $elementValue;
1701 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering:
1706 This is a hook that is invoked by the rendering system before the corresponding element is rendered.
1707 Use this to access previously submitted values and/or modify the ``FormRuntime`` before an element is outputted to the browser.
1708 This hook is called after all validations and property mappings are done.
1710 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-connect:
1717 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'][<useATimestampAsKeyPlease>]
1718 = \VENDOR\YourNamespace\YourClass::class;
1721 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-use:
1729 * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1730 * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable
1733 public function beforeRendering(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable)
1738 .. _apireference-finisheroptions:
1743 .. _apireference-finisheroptions-closurefinisher:
1748 This finisher can only be used in programmatically-created forms. It makes it
1749 possible to execute one's own finisher code without having to implement/
1750 declare this finisher.
1756 $closureFinisher = $this->objectManager->get(ClosureFinisher::class);
1757 $closureFinisher->setOption('closure', function($finisherContext) {
1758 $formRuntime = $finisherContext->getFormRuntime();
1761 $formDefinition->addFinisher($closureFinisher);
1764 .. _apireference-finisheroptions-closurefinisher-options:
1769 .. _apireference-finisheroptions-closurefinisher-options-closure:
1780 :aspect:`Default value`
1784 .. _apireference-finisheroptions-confirmationfinisher:
1786 Confirmation finisher
1787 ---------------------
1789 A simple finisher that outputs a given text.
1791 Usage within form definition
1793 .. code-block:: yaml
1795 identifier: example-form
1801 identifier: Confirmation
1803 message: 'Thx for using TYPO3'
1811 $formDefinition->createFinisher('Confirmation', [
1815 or create manually (not preferred)
1819 $confirmationFinisher = $this->objectManager->get(ConfirmationFinisher::class);
1820 $confirmationFinisher->setOptions([
1823 $formDefinition->addFinisher($confirmationFinisher);
1826 .. _apireference-finisheroptions-confirmationfinisher-options:
1831 .. _apireference-finisheroptions-confirmationfinisher-options-message:
1842 :aspect:`Default value`
1843 The form has been submitted.
1846 .. _apireference-finisheroptions-deleteuploadsfinisher:
1848 DeleteUploads finisher
1849 ----------------------
1851 This finisher remove the currently submited files.
1852 Use this finisher e.g after the email finisher if you don't want to keep the files online.
1855 Usage within form definition
1857 .. code-block:: yaml
1859 identifier: example-form
1865 identifier: DeleteUploads
1873 $formDefinition->createFinisher('DeleteUploads');
1875 or create manually (not preferred)
1879 $deleteUploadsFinisher = $this->objectManager->get(DeleteUploadsFinisher::class);
1880 $formDefinition->addFinisher($deleteUploadsFinisher);
1883 .. _apireference-finisheroptions-emailfinisher:
1888 This finisher sends an email to one recipient.
1889 EXT:form uses 2 EmailFinisher declarations with the identifiers ``EmailToReceiver`` and ``EmailToSender``.
1891 Usage within form definition
1893 .. code-block:: yaml
1895 identifier: example-form
1901 identifier: EmailToReceiver
1903 subject: 'Your message'
1904 recipientAddress: your.company@example.com
1905 recipientName: 'Your Company name'
1906 senderAddress: 'form@example.com'
1907 senderName: 'form submitter'
1915 $formDefinition->createFinisher('EmailToReceiver', [
1916 'subject' => 'Your message',
1917 'recipientAddress' => 'your.company@example.com',
1918 'recipientName' => 'Your Company name',
1919 'senderAddress' => 'form@example.com',
1920 'senderName' => 'form submitter',
1923 or create manually (not preferred)
1927 $emailFinisher = $this->objectManager->get(EmailFinisher::class);
1928 $emailFinisher->setOptions([
1929 'subject' => 'Your message',
1930 'recipientAddress' => 'your.company@example.com',
1931 'recipientName' => 'Your Company name',
1932 'senderAddress' => 'form@example.com',
1933 'senderName' => 'form submitter',
1935 $formDefinition->addFinisher($emailFinisher);
1938 .. _apireference-finisheroptions-emailfinisher-options:
1943 .. _apireference-finisheroptions-emailfinisher-options-subject:
1954 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1957 :aspect:`Description`
1958 Subject of the email
1961 .. _apireference-finisheroptions-emailfinisher-options-recipientaddress:
1972 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1975 :aspect:`Description`
1976 Email address of the recipient (To)
1979 .. _apireference-finisheroptions-emailfinisher-options-recipientname:
1990 :aspect:`Default value`
1993 :aspect:`Description`
1994 Human-readable name of the recipient
1997 .. _apireference-finisheroptions-emailfinisher-options-senderaddress:
2008 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2011 :aspect:`Description`
2012 Email address of the sender/ visitor (From)
2015 .. _apireference-finisheroptions-emailfinisher-options-sendername:
2026 :aspect:`Default value`
2029 :aspect:`Description`
2030 Human-readable name of the sender
2033 .. _apireference-finisheroptions-emailfinisher-options-replytoaddress:
2044 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2047 :aspect:`Description`
2048 Email address of to be used as reply-to email (use multiple addresses with an array)
2051 For the moment, the ``form editor`` cannot deal with multiple reply-to addresses (use multiple addresses with an array)
2054 .. _apireference-finisheroptions-emailfinisher-options-carboncopyaddress:
2065 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2068 :aspect:`Description`
2069 Email address of the copy recipient (use multiple addresses with an array)
2072 For the moment, the ``form editor`` cannot deal with multiple copy recipient addresses (use multiple addresses with an array)
2075 .. _apireference-finisheroptions-emailfinisher-options-blindcarboncopyaddress:
2077 blindCarbonCopyAddress
2078 ++++++++++++++++++++++
2086 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2089 :aspect:`Description`
2090 Email address of the blind copy recipient (use multiple addresses with an array)
2093 For the moment, the ``form editor`` cannot deal with multiple blind copy recipient addresses (use multiple addresses with an array)
2096 .. _apireference-finisheroptions-emailfinisher-options-format:
2107 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2110 :aspect:`possible values`
2113 :aspect:`Description`
2114 The format of the email. By default mails are sent as HTML.
2117 .. _apireference-finisheroptions-emailfinisher-options-attachuploads:
2128 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2131 :aspect:`Description`
2132 If set, all uploaded items are attached to the email.
2135 .. _apireference-finisheroptions-emailfinisher-options-translation-translationfile:
2137 translation.translationFile
2138 +++++++++++++++++++++++++++
2146 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2149 :aspect:`Description`
2150 If set, this translation file(s) will be used for finisher option translations.
2151 If not set, the translation file(s) from the 'Form' element will be used.
2152 Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
2155 .. _apireference-finisheroptions-emailfinisher-options-translation-language:
2157 translation.language
2158 ++++++++++++++++++++
2166 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2169 :aspect:`Description`
2170 If not set, the finisher options are translated depending on the current frontend language (if translations exists).
2171 This option allows you to force translations for a given sys_language isocode, e.g 'dk' or 'de'.
2172 Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
2175 .. _apireference-finisheroptions-emailfinisher-options-templatepathandfilename:
2177 templatePathAndFilename
2178 +++++++++++++++++++++++
2186 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2187 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/{@format}.html'
2189 :aspect:`Description`
2190 Template path and filename for the mail body.
2191 The placeholder {\@format} will be replaced with the value from option ``format``
2194 .. _apireference-finisheroptions-emailfinisher-options-layoutrootpaths:
2205 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2208 :aspect:`Description`
2212 .. _apireference-finisheroptions-emailfinisher-options-partialrootpaths:
2223 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2226 :aspect:`Description`
2230 .. _apireference-finisheroptions-emailfinisher-options-variables:
2241 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2244 :aspect:`Description`
2245 associative array of variables which are available inside the Fluid template
2248 .. _apireference-finisheroptions-flashmessagefinisher:
2250 FlashMessage finisher
2251 ---------------------
2253 A simple finisher that adds a message to the FlashMessageContainer.
2256 Usage within form definition
2258 .. code-block:: yaml
2260 identifier: example-form
2266 identifier: FlashMessage
2268 messageBody: 'Thx for using TYPO3'
2269 messageTitle: 'Merci'
2278 $formDefinition->createFinisher('FlashMessage', [
2279 'messageBody' => 'Thx for using TYPO3',
2280 'messageTitle' => 'Merci',
2281 'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
2284 or create manually (not preferred)
2288 $flashMessageFinisher = $this->objectManager->get(FlashMessageFinisher::class);
2289 $flashMessageFinisher->setOptions([
2290 'messageBody' => 'Thx for using TYPO3',
2291 'messageTitle' => 'Merci',
2292 'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
2294 $formDefinition->addFinisher($flashMessageFinisher);
2297 .. _apireference-finisheroptions-flashmessagefinisher-options:
2302 .. _apireference-finisheroptions-flashmessagefinisher-options-messagebody:
2313 :aspect:`Default value`
2316 :aspect:`Description`
2317 The flash message body
2320 .. _apireference-finisheroptions-flashmessagefinisher-options-messagetitle:
2331 :aspect:`Default value`
2334 :aspect:`Description`
2335 The flash message title
2338 .. _apireference-finisheroptions-flashmessagefinisher-options-messagearguments:
2349 :aspect:`Default value`
2352 :aspect:`Description`
2353 The flash message arguments, if needed
2356 .. _apireference-finisheroptions-flashmessagefinisher-options-messagecode:
2367 :aspect:`Default value`
2370 :aspect:`Description`
2371 The flash message code, if needed
2374 .. _apireference-finisheroptions-flashmessagefinisher-options-severity:
2385 :aspect:`Default value`
2386 \TYPO3\CMS\Core\Messaging\AbstractMessage::OK (0)
2388 :aspect:`Description`
2389 The flash message severity code.
2390 See \TYPO3\CMS\Core\Messaging\AbstractMessage constants for the codes.
2393 .. _apireference-finisheroptions-redirectfinisher:
2398 A simple finisher that redirects to another page.
2401 Usage within form definition
2403 .. code-block:: yaml
2405 identifier: example-form
2411 identifier: Redirect
2414 additionalParameters: 'param1=value1¶m2=value2'
2422 $formDefinition->createFinisher('Redirect', [
2424 'additionalParameters' => 'param1=value1¶m2=value2',
2427 or create manually (not preferred)
2431 $redirectFinisher = $this->objectManager->get(RedirectFinisher::class);
2432 $redirectFinisher->setOptions([
2434 'additionalParameters' => 'param1=value1¶m2=value2',
2436 $formDefinition->addFinisher($redirectFinisher);
2439 .. _apireference-finisheroptions-redirectfinisher-options:
2444 .. _apireference-finisheroptions-redirectfinisher-options-pageuid:
2455 :aspect:`Default value`
2458 :aspect:`Description`
2459 Redirect to this page uid
2462 .. _apireference-finisheroptions-redirectfinisher-options-additionalparameters:
2464 additionalParameters
2465 ++++++++++++++++++++
2473 :aspect:`Default value`
2476 :aspect:`Description`
2477 Additional parameters which should be used on the target page
2480 .. _apireference-finisheroptions-redirectfinisher-options-delay:
2491 :aspect:`Default value`
2494 :aspect:`Description`
2495 The redirect delay in seconds.
2498 .. _apireference-finisheroptions-redirectfinisher-options-statuscode:
2509 :aspect:`Default value`
2512 :aspect:`Description`
2513 The HTTP status code for the redirect. Default is "303 See Other".
2516 .. _apireference-finisheroptions-savetodatabasefinisher:
2518 SaveToDatabase finisher
2519 -----------------------
2521 This finisher saves the data from a submitted form into a database table.
2524 Usage within form definition
2526 .. code-block:: yaml
2528 identifier: example-form
2534 identifier: SaveToDatabase
2540 databaseColumnMappings:
2544 textfield-identifier-1:
2545 mapOnDatabaseColumn: 'first_name'
2546 textfield-identifier-2:
2547 mapOnDatabaseColumn: 'last_name'
2548 textfield-identifier-3:
2549 mapOnDatabaseColumn: 'username'
2551 mapOnDatabaseColumn: 'password'
2552 skipIfValueIsEmpty: true
2560 $formDefinition->createFinisher('SaveToDatabase', [
2561 'table' => 'fe_users',
2566 'databaseColumnMappings' => [
2567 'pid' => ['value' => 1],
2570 'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
2571 'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
2572 'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
2573 'advancedpassword-1' => [
2574 'mapOnDatabaseColumn' => 'password',
2575 'skipIfValueIsEmpty' => true,
2580 or create manually (not preferred)
2584 $saveToDatabaseFinisher = $this->objectManager->get(SaveToDatabaseFinisher::class);
2585 $saveToDatabaseFinisher->setOptions([
2586 'table' => 'fe_users',
2591 'databaseColumnMappings' => [
2592 'pid' => ['value' => 1],
2595 'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
2596 'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
2597 'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
2598 'advancedpassword-1' => [
2599 'mapOnDatabaseColumn' => 'password',
2600 'skipIfValueIsEmpty' => true,
2604 $formDefinition->addFinisher($saveToDatabaseFinisher);
2606 You can write options as an array to perform multiple database operations.
2608 Usage within form definition
2610 .. code-block:: yaml
2612 identifier: example-form
2618 identifier: SaveToDatabase
2623 databaseColumnMappings:
2627 table: 'my_other_table'
2631 databaseColumnMappings:
2633 value: '{SaveToDatabase.insertedUids.1}'
2641 $formDefinition->createFinisher('SaveToDatabase', [
2643 'table' => 'my_table',
2645 'databaseColumnMappings' => [
2646 'some_column' => ['value' => 'cool'],
2650 'table' => 'my_other_table',
2655 'databaseColumnMappings' => [
2656 'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
2661 or create manually (not preferred)
2665 $saveToDatabaseFinisher = $this->objectManager->get(SaveToDatabaseFinisher::class);
2666 $saveToDatabaseFinisher->setOptions([
2668 'table' => 'my_table',
2670 'databaseColumnMappings' => [
2671 'some_column' => ['value' => 'cool'],
2675 'table' => 'my_other_table',
2680 'databaseColumnMappings' => [
2681 'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
2685 $formDefinition->addFinisher($saveToDatabaseFinisher);
2688 This perform 2 database operations.
2689 One insert and one update.
2690 You can access the inserted uids through '{SaveToDatabase.insertedUids.<theArrayKeyNumberWithinOptions>}'
2691 If you perform a insert operation, the value of the inserted database row will be stored within the FinisherVariableProvider.
2692 <theArrayKeyNumberWithinOptions> references to the numeric options.* key.
2695 .. _apireference-finisheroptions-savetodatabasefinisher-options:
2700 .. _apireference-finisheroptions-savetodatabasefinisher-options-table:
2711 :aspect:`Default value`
2714 :aspect:`Description`
2715 Insert or update values into this table.
2718 .. _apireference-finisheroptions-savetodatabasefinisher-options-mode:
2729 :aspect:`Default value`
2732 :aspect:`Possible values`
2735 :aspect:`Description`
2736 ``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
2738 ``update`` will update a given database row with the values from the submitted form and/or some predefined values. 'options.whereClause' is then required.
2741 .. _apireference-finisheroptions-savetodatabasefinisher-options-whereclause:
2750 Yes, if mode = update
2752 :aspect:`Default value`
2755 :aspect:`Description`
2756 This where clause will be used for a database update action
2759 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements:
2770 :aspect:`Default value`
2773 :aspect:`Description`
2774 Use ``options.elements`` to map form element values to existing database columns.
2775 Each key within ``options.elements`` has to match with a form element identifier.
2776 The value for each key within ``options.elements`` is an array with additional informations.
2779 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-mapondatabasecolumn:
2781 elements.<formElementIdentifier>.mapOnDatabaseColumn
2782 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2790 :aspect:`Default value`
2793 :aspect:`Description`
2794 The value from the submitted form element with the identifier ``<formElementIdentifier>`` will be written into this database column.
2797 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-skipifvalueisempty:
2799 elements.<formElementIdentifier>.skipIfValueIsEmpty
2800 +++++++++++++++++++++++++++++++++++++++++++++++++++
2808 :aspect:`Default value`
2811 :aspect:`Description`
2812 Set this to true if the database column should not be written if the value from the submitted form element with the identifier
2813 ``<formElementIdentifier>`` is empty (think about password fields etc.)
2816 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-savefileidentifierinsteadofuid:
2818 elements.<formElementIdentifier>.saveFileIdentifierInsteadOfUid
2819 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2827 :aspect:`Default value`
2830 :aspect:`Description`
2831 Set this to true if the database column should not be written if the value from the submitted form element with the identifier
2832 ``<formElementIdentifier>`` is empty (think about password fields etc.)
2834 This setting only rules for form elements which creates a FAL object like ``FileUpload`` or ``ImageUpload``.
2835 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
2836 FAL identifier (1:/user_uploads/some_uploaded_pic.jpg) instead.
2839 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings:
2841 databaseColumnMappings
2842 ++++++++++++++++++++++
2850 :aspect:`Default value`
2853 :aspect:`Description`
2854 Use this to map database columns to static values.
2855 Each key within ``options.databaseColumnMappings`` has to match with an existing database column.
2856 The value for each key within ``options.databaseColumnMappings`` is an array with additional informations.
2858 This mapping is done *before* the ``options.element`` mapping.
2859 This means if you map a database column to a value through ``options.databaseColumnMappings`` and map a submitted
2860 form element value to the same database column through ``options.element``, the submitted form element value
2861 will override the value you set within ``options.databaseColumnMappings``.
2864 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.value:
2866 databaseColumnMappings.<databaseColumnName>.value
2867 +++++++++++++++++++++++++++++++++++++++++++++++++
2875 :aspect:`Default value`
2878 :aspect:`Description`
2879 The value which will be written to the database column.
2880 You can also use the :ref:`FormRuntime accessor feature<concepts-frontendrendering-codecomponents-customfinisherimplementations-accessingoptions-formruntimeaccessor>` to access every getable property from the ``FormRuntime``
2881 In short: use something like ``{<formElementIdentifier>}`` to get the value from the submitted form element with the identifier ``<formElementIdentifier>``.
2883 If you use the FormRuntime accessor feature within ``options.databaseColumnMappings``, the functionality is nearly identical
2884 to the ``options.elements`` configuration variant.
2887 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.skipifvalueisempty:
2889 databaseColumnMappings.<databaseColumnName>.skipIfValueIsEmpty
2890 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2898 :aspect:`Default value`
2901 :aspect:`Description`
2902 Set this to true if the database column should not be written if the value from ``options.databaseColumnMappings.<databaseColumnName>.value`` is empty.
2906 .. _apireference-formeditor:
2912 .. _apireference-formeditor-hooks:
2917 EXT:form implements various hooks so that forms can be manipulated while being
2921 .. _apireference-formeditor-hooks-beforeformcreate:
2926 The form manager calls the 'beforeFormCreate' hook.
2929 .. _apireference-formeditor-hooks-beforeformcreate-connect:
2936 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormCreate'][<useATimestampAsKeyPlease>]
2937 = \VENDOR\YourNamespace\YourClass::class;
2940 .. _apireference-formeditor-hooks-beforeformcreate-use:
2948 * @param string $formPersistenceIdentifier
2949 * @param array $formDefinition
2952 public function beforeFormCreate(string $formPersistenceIdentifier, array $formDefinition): array
2954 return $formDefinition;
2958 .. _apireference-formeditor-hooks-beforeformduplicate:
2963 The form manager call the 'beforeFormDuplicate' hook.
2966 .. _apireference-formeditor-hooks-beforeformduplicate-connect:
2973 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDuplicate'][<useATimestampAsKeyPlease>]
2974 = \VENDOR\YourNamespace\YourClass::class;
2977 .. _apireference-formeditor-hooks-beforeformduplicate-use:
2985 * @param string $formPersistenceIdentifier
2986 * @param array $formDefinition
2989 public function beforeFormDuplicate(string $formPersistenceIdentifier, array $formDefinition): array
2991 return $formDefinition;
2995 .. _apireference-formeditor-hooks-beforeformdelete:
3000 The form manager call the 'beforeFormDelete' hook.
3003 .. _apireference-formeditor-hooks-beforeformdelete-connect:
3010 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDelete'][<useATimestampAsKeyPlease>]
3011 = \VENDOR\YourNamespace\YourClass::class;
3014 .. _apireference-formeditor-hooks-beforeformdelete-use:
3022 * @param string $formPersistenceIdentifier
3025 public function beforeFormDelete(string $formPersistenceIdentifier)
3030 .. _apireference-formeditor-hooks-beforeformsave:
3035 The form editor call the 'beforeFormSave' hook.
3038 .. _apireference-formeditor-hooks-beforeformsave-connect:
3045 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'][<useATimestampAsKeyPlease>]
3046 = \VENDOR\YourNamespace\YourClass::class;
3049 .. _apireference-formeditor-hooks-beforeformsave-use:
3057 * @param string $formPersistenceIdentifier
3058 * @param array $formDefinition
3061 public function beforeFormSave(string $formPersistenceIdentifier, array $formDefinition): array
3063 return $formDefinition;
3068 .. _apireference-formeditor-stage:
3074 .. _apireference-formeditor-stage-commonabstractformelementtemplates:
3076 Common abstract view form element templates
3077 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3079 The basic idea of the ``abstract view`` is to give a quick overview of the
3080 configuration of form elements, without having to click them in order to view
3081 the detailed configuration in the ``Inspector``. The ``form editor`` requires
3082 for each form element an inline HTML template and the corresponding JavaScript
3083 code. Information matching inline HTML templates to the appropriate form
3084 elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
3085 At this point, the key identifying the form element follows a convention:
3086 ``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
3087 ``form editor`` which inline HTML template should be loaded for the respective
3088 form element. This template is then cloned via JavaScript, brought to life
3089 using the form element configuration and shown in the ``Stage`` component.
3091 You can read about how particular form elements are mapped to inline HTML
3092 templates and how the corresponding JavaScript code are executed :ref:`here <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`.
3094 The form element inline HTML templates and the corresponding JavaScript code
3095 are configured for reuse. In this way, most form elements you create should be
3096 able to access the components delivered in EXT:form, without requiring separate
3097 implementations (at least we hope so). For your own implementations, study
3098 EXT:form stage templates, which is found under ``Resources/Private/Backend/Partials/FormEditor/Stage/*``.
3099 The corresponding JavaScript code is found under ``Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js``.
3100 The method ``_renderTemplateDispatcher()`` shows, which methods will be used to
3101 render the respective form elements.
3103 Essentially, two different inline HTML templates exists that can be rendered
3104 with two different JavaScript methods, which are described below. The other
3105 inline HTML templates are almost all versions of these two basic variants and
3106 show extra/ other form-element information. The same applies to the
3107 corresponding JavaScript codes.
3110 .. _apireference-formeditor-stage-commonabstractformelementtemplates-simpletemplate:
3112 Stage/SimpleTemplate
3113 ++++++++++++++++++++
3115 This template displays the ``label`` property of the form element. Depending on
3116 the JavaScript rendering method used, a validator icon will be shown on the
3117 right as soon as a validator is added to the form element. In this case, the
3118 used validator labels are likewise displayed, if the form element is selected
3119 and/ or the cursor hovers over the form element. This template should generally
3120 be enough for all possible, self-defined form elements.
3122 The ``Stage/SimpleTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
3123 with the method ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``.
3126 .. _apireference-formeditor-stage-commonabstractformelementtemplates-selecttemplate:
3128 Stage/SelectTemplate
3129 ++++++++++++++++++++
3131 This template behaves like the ``Stage/SimpleTemplate`` except that it also
3132 shows the chosen options labels of the form elements. This is naturally only
3133 possible for form elements that have ``properties.options.*`` values, e.g.
3136 .. code-block:: yaml
3139 identifier: multicheckbox-1
3140 label: 'Multi checkbox'
3147 The template will now list 'label1' and 'label2'.
3149 You can copy this template variant for your own form element, if that form-
3150 element template also lists array values, which, however, are not found under
3151 ``properties.options.*``. For this purpose, the 'Stage/FileUploadTemplate' is
3152 an example. It is basically the 'Stage/SelectTemplate' template, with one
3155 In the ``FileUpload`` form element, multiple property values are available
3156 under ``properties.allowedMimeTypes.*`` as an array.
3158 .. code-block:: yaml
3161 identifier: fileupload-1
3162 label: 'File upload'
3164 saveToFileMount: '1:/user_upload/'
3166 - application/msexcel
3170 Stage/SelectTemplate
3172 .. code-block:: html
3174 <div data-identifier="multiValueContainer" data-template-property="properties.options">
3177 Stage/FileUploadTemplate
3179 .. code-block:: html
3181 <div data-identifier="multiValueContainer" data-template-property="properties.allowedMimeTypes">
3184 ``data-template-property`` contains the path to the property, which is to be
3185 read out of the form element and then shown in the template.
3187 The ``Stage/SelectTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
3188 with the method ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``.
3192 .. _apireference-formeditor-basicjavascriptconcepts:
3194 Basic JavaScript Concepts
3195 -------------------------
3198 .. _apireference-formeditor-basicjavascriptconcepts-events:
3203 EXT:form implements the ``publish/subscribe pattern`` to put the event handling
3204 into effect. To learn more about this pattern, you should read
3205 https://addyosmani.com/resources/essentialjsdesignpatterns/book/.
3206 Note that the order of the subscriber is not manipulable and that information
3207 flow between the subscribers does not exist. All events must be asynchronously
3213 .. code-block:: javascript
3215 getPublisherSubscriber().publish('eventname', [argumentToPublish1, argumentToPublish2, ...]);
3218 Subscribe to an event:
3220 .. code-block:: javascript
3222 var subscriberToken = getPublisherSubscriber().subscribe('eventname', function(topic, args) {
3223 // args[0] = argumentToPublish1
3224 // args[1] = argumentToPublish2
3229 Unsubscribe an event subscriber:
3231 .. code-block:: javascript
3233 getPublisherSubscriber().unsubscribe(subscriberToken);
3236 EXT:form itself publishes and subscribes to the following events:
3238 .. _apireference-formeditor-basicjavascriptconcepts-events-ajax-beforesend:
3243 Each Ajax request is called before this event is sent. EXT:form uses this event
3244 to display the spinner icon on the save button.
3247 Subscribe to the event:
3249 .. code-block:: javascript
3258 getPublisherSubscriber().subscribe('ajax/beforeSend', function(topic, args) {
3262 .. _apireference-formeditor-basicjavascriptconcepts-events-ajax-complete:
3267 Each Ajax request is called after the end of this event. EXT:form uses this
3268 event to remove the spinner icon on the save button.
3271 Subscribe to the event:
3273 .. code-block:: javascript
3282 getPublisherSubscriber().subscribe('ajax/complete', function(topic, args) {
3286 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-error:
3291 This event is called if the Ajax request, which is used to save the form or to
3292 render the current page of the form in the ``preview view``, fails. EXT:form
3293 uses this event to show an error message as a flash message and to show the
3294 received error text in the ``preview view``.
3297 Subscribe to the event:
3299 .. code-block:: javascript
3307 * args[1] = textStatus
3308 * args[2] = errorThrown
3311 getPublisherSubscriber().subscribe('core/ajax/error', function(topic, args) {
3315 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-renderformdefinitionpage-success:
3317 core/ajax/renderFormDefinitionPage/success
3318 ++++++++++++++++++++++++++++++++++++++++++
3320 This event is called if the Ajax request that is used to render the current
3321 page of the form in the ``preview view`` was successful. EXT:form uses this
3322 event to display the rendered form in the ``preview view``.
3325 Subscribe to the event:
3327 .. code-block:: javascript
3335 * args[1] = pageIndex
3338 getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', function(topic, args) {
3342 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-saveformdefinition-success:
3344 core/ajax/saveFormDefinition/success
3345 ++++++++++++++++++++++++++++++++++++
3347 This event is called if the Ajax request that is used to save the form was
3348 successful. EXT:form uses this event to display a success message as a flash
3349 message. The ``form editor`` is also informed that no unsaved content currently
3353 Subscribe to the event:
3355 .. code-block:: javascript
3365 getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', function(topic, args) {
3369 .. _apireference-formeditor-basicjavascriptconcepts-events-core-applicationstate-add:
3371 core/applicationState/add
3372 +++++++++++++++++++++++++
3374 The addition/ deletion and movement of form elements und property collection
3375 elements (validators/ finishers) is saved in an internal stack so that the
3376 undo/ redo function can be implemented. This event is called whenever the
3377 current state is added to the stack. EXT:form uses this event to reset the
3378 enabled/ disabled state of the undo/ redo buttons.
3381 Subscribe to the event:
3383 .. code-block:: javascript
3390 * args[0] = applicationState
3391 * args[1] = stackPointer
3392 * args[2] = stackSize
3395 getPublisherSubscriber().subscribe('core/applicationState/add', function(topic, args) {
3399 .. _apireference-formeditor-basicjavascriptconcepts-events-core-currentlyselectedformelementchanged:
3401 core/currentlySelectedFormElementChanged
3402 ++++++++++++++++++++++++++++++++++++++++
3404 The method ``getFormEditorApp().setCurrentlySelectedFormElement()`` tells the
3405 ``form editor`` which form element should currently be dealt with. This method
3406 calls this event at the end.
3409 Subscribe to the event:
3411 .. code-block:: javascript
3418 * args[0] = formElement
3421 getPublisherSubscriber().subscribe('core/currentlySelectedFormElementChanged', function(topic, args) {
3425 .. _apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged:
3427 core/formElement/somePropertyChanged
3428 ++++++++++++++++++++++++++++++++++++
3430 Each :ref:`FormElement model<apireference-formeditor-basicjavascriptconcepts-formelementmodel>`
3431 can write properties into the ``FormElement model`` through the methods ``get``
3432 and ``set``. Each property path can register an event name for the publisher
3433 through the method ``on``. This event is then always called when a property
3434 path is written via ``set``. Read :ref:`FormElement model<concepts-formeditor-basicjavascriptconcepts-formelementmodel>`
3435 for more information. EXT:form automatically registers for all known property
3436 paths of a form element the event ``core/formElement/somePropertyChanged``.
3437 This means that every property written via ``set`` calls this event. Among
3438 other things, EXT:form uses this event for, for example, updating the label of
3439 a form element in other components (e.g. ``Tree`` component ) when this label
3440 is changed. Furthermore, any validation errors from form element properties
3441 are indicated by this event in the ``Tree`` component.
3444 Subscribe to the event:
3446 .. code-block:: javascript
3453 * args[0] = propertyPath
3455 * args[2] = oldValue
3456 * args[3] = formElementIdentifierPath
3459 getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', function(topic, args) {
3463 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-moved:
3465 view/collectionElement/moved
3466 ++++++++++++++++++++++++++++
3468 The method ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``
3469 calls this event at the end. EXT:form uses this event to re-render the
3470 ``Inspector`` component as soon as a property collection element (validator/
3474 Subscribe to the event:
3476 .. code-block:: javascript
3483 * args[0] = movedCollectionElementIdentifier
3484 * args[1] = previousCollectionElementIdentifier
3485 * args[2] = nextCollectionElementIdentifier
3486 * args[3] = collectionName
3489 getPublisherSubscriber().subscribe('view/collectionElement/moved', function(topic, args) {
3493 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-new-added:
3495 view/collectionElement/new/added
3496 ++++++++++++++++++++++++++++++++
3498 The method ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``
3499 calls this event at the end. EXT:form uses this event to re-render the
3500 ``Inspector`` component as soon as a property collection element (validator/
3501 finisher) is created and added.
3504 Subscribe to the event:
3506 .. code-block:: javascript
3513 * args[0] = collectionElementIdentifier
3514 * args[1] = collectionName
3515 * args[2] = formElement
3516 * args[3] = collectionElementConfiguration
3517 * args[4] = referenceCollectionElementIdentifier
3520 getPublisherSubscriber().subscribe('view/collectionElement/new/added', function(topic, args) {
3524 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-removed:
3526 view/collectionElement/removed
3527 ++++++++++++++++++++++++++++++
3529 The method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``
3530 calls this event at the end. EXT:form uses this event to re-render the
3531 ``Inspector`` component as soon as a property collection element (validator/
3532 finisher) is removed.
3535 Subscribe to the event:
3537 .. code-block:: javascript
3544 * args[0] = collectionElementIdentifier
3545 * args[1] = collectionName
3546 * args[2] = formElement
3549 getPublisherSubscriber().subscribe('view/collectionElement/removed', function(topic, args) {
3553 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted:
3555 view/formElement/inserted
3556 +++++++++++++++++++++++++
3558 The method ``getFormEditorApp().getViewModel().createAndAddFormElement()`` and
3559 the event :ref:`view/insertElements/perform/after<apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after>`
3560 call this event at the end. EXT:form uses this event to set the current
3561 to-be-processed form element (``getFormEditorApp().setCurrentlySelectedFormElement()``)
3562 and to re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
3565 Subscribe to the event:
3567 .. code-block:: javascript
3574 * args[0] = newFormElement
3577 getPublisherSubscriber().subscribe('view/formElement/inserted', function(topic, args) {
3581 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-moved:
3583 view/formElement/moved
3584 ++++++++++++++++++++++
3586 The method ``getFormEditorApp().getViewModel().moveFormElement()`` calls this
3590 Subscribe to the event:
3592 .. code-block:: javascript
3599 * args[0] = movedFormElement
3602 getPublisherSubscriber().subscribe('view/formElement/moved', function(topic, args) {
3606 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-removed:
3608 view/formElement/removed
3609 ++++++++++++++++++++++++
3611 The method ``getFormEditorApp().getViewModel().removeFormElement()`` calls this
3612 event at the end. EXT:form uses this event to set the current to-be-processed
3613 form element (``getFormEditorApp().setCurrentlySelectedFormElement()``) and to
3614 re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
3617 Subscribe to the event:
3619 .. code-block:: javascript
3626 * args[0] = parentFormElement
3629 getPublisherSubscriber().subscribe('view/formElement/removed', function(topic, args) {
3633 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-close-clicked:
3635 view/header/button/close/clicked
3636 ++++++++++++++++++++++++++++++++
3638 The onClick event of the "Close" button in the ``form editor's`` header section
3639 calls this event. EXT:form uses this event to display a warning message in case
3640 there are unsaved changes.
3643 Subscribe to the event:
3645 .. code-block:: javascript
3654 getPublisherSubscriber().subscribe('view/header/button/close/clicked', function(topic, args) {
3658 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-newpage-clicked:
3660 view/header/button/newPage/clicked
3661 ++++++++++++++++++++++++++++++++++
3663 The onClick event of the "new page" button in the ``form editor's`` header
3664 section calls this event. EXT:form uses this event to display the "new page"
3668 Subscribe to the event:
3670 .. code-block:: javascript
3677 * args[0] = targetEvent
3680 getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', function(topic, args) {
3684 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-save-clicked:
3686 view/header/button/save/clicked
3687 +++++++++++++++++++++++++++++++
3689 The onClick event of the "save" button in the ``form editor's`` header section
3690 calls this event. EXT:form uses this event either to display a dialog box with
3691 the element in question (if there are validation errors) or to save the ``form
3692 definition`` (if there are no validation errors).
3695 Subscribe to the event:
3697 .. code-block:: javascript
3706 getPublisherSubscriber().subscribe('view/header/button/save/clicked', function(topic, args) {
3710 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-formsettings-clicked:
3712 view/header/formSettings/clicked
3713 ++++++++++++++++++++++++++++++++
3715 The onClick event of the "settings" button in the ``form editor's`` header
3716 section calls this event. EXT:form uses this event to select the root form
3720 Subscribe to the event:
3722 .. code-block:: javascript
3731 getPublisherSubscriber().subscribe('view/header/formSettings/clicked', function(topic, args) {
3735 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after:
3737 view/insertElements/perform/after
3738 +++++++++++++++++++++++++++++++++
3740 This event is called from the "new element" dialog box upon selection of a form
3743 - if "After" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
3744 - if the "Create new element" button in the form-element toolbar for non-composite elements is clicked.
3746 EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``)
3747 and then move (``getFormEditorApp().getViewModel().moveFormElement()``) it
3748 below the currently selected element (sibling). At the end of this event, the
3749 event :ref:`view/formElement/inserted<apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted>`
3750 is called. The event ``view/formElement/inserted`` in ``getFormEditorApp().getViewModel().createAndAddFormElement()``
3751 was previously deactivated.
3754 Subscribe to the event:
3756 .. code-block:: javascript
3763 * args[0] = formElementType
3766 getPublisherSubscriber().subscribe('view/insertElements/perform/after', function(topic, args) {
3770 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-bottom:
3772 view/insertElements/perform/bottom
3773 ++++++++++++++++++++++++++++++++++
3775 This event is called from the "new element" dialog box upon selection of a form
3778 - if, in the ``abstract view`` mode, the "Create new element" button at the end of the ``Stage`` component is clicked.
3780 EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3781 This element is always created as the last element of the currently selected
3785 Subscribe to the event:
3787 .. code-block:: javascript
3794 * args[0] = formElementType
3797 getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', function(topic, args) {
3801 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-inside:
3803 view/insertElements/perform/inside
3804 ++++++++++++++++++++++++++++++++++
3806 This event is called from the "new element" dialog box upon selection of a form
3809 - if "Inside" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
3811 EXT:form uses this event to create a new form element as a child element of the
3812 currently selected element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3815 Subscribe to the event:
3817 .. code-block:: javascript
3824 * args[0] = formElementType
3827 getPublisherSubscriber().subscribe('view/insertElements/perform/inside', function(topic, args) {
3831 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertpages-perform:
3833 view/insertPages/perform
3834 ++++++++++++++++++++++++
3836 This event is called from the "new element" dialog box upon selection of a page
3839 - if the "Create new page" icon in the header section is clicked.
3840 - if the "Create new page" button in the ``Tree`` component is clicked.
3842 EXT:form uses this event to create a new page after the currently selected page
3843 (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3846 Subscribe to the event:
3848 .. code-block:: javascript
3855 * args[0] = formElementType
3858 getPublisherSubscriber().subscribe('view/insertPages/perform', function(topic, args) {
3862 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-existing-selected:
3864 view/inspector/collectionElement/existing/selected
3865 ++++++++++++++++++++++++++++++++++++++++++++++++++
3867 The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
3868 and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
3869 are used to display the available validators/ finishers for a form element as a
3870 select box. Furthermore, these ``inspector editors`` indicate that in the
3871 ``form definition``, validators/ finishers for the currently selected element
3872 already exist. This occurs through the event ``view/inspector/collectionElement/existing/selected``.
3873 EXT:form uses this event to render these validators/ finishers and their
3874 tentatively configured ``inspector editors`` (``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``).
3876 Subscribe to the event:
3878 .. code-block:: javascript
3885 * args[0] = collectionElementIdentifier
3886 * args[1] = collectionName
3889 getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', function(topic, args) {
3893 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-new-selected:
3895 view/inspector/collectionElement/new/selected
3896 +++++++++++++++++++++++++++++++++++++++++++++
3898 The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
3899 and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
3900 are used to display the available validators/ finishers for a form element as a
3901 select box. The onChange event of the select box then calls this event. In
3902 addition, the ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
3903 calls this event when a checkbox is chosen. EXT:form uses this event to add and
3904 render the validator/ finisher of the ``form definition`` via ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``.
3907 Subscribe to the event:
3909 .. code-block:: javascript
3916 * args[0] = collectionElementIdentifier
3917 * args[1] = collectionName
3920 getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', function(topic, args) {
3924 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-dnd-update:
3926 view/inspector/collectionElements/dnd/update
3927 ++++++++++++++++++++++++++++++++++++++++++++
3929 EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
3930 drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
3931 the ``view/inspector/collectionElements/dnd/update`` event if a property
3932 collection element in the ``Inspector`` component is sorted. EXT:form uses this
3933 event to move the validator/ finisher in the ``form definition`` via the method
3934 ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``.
3937 Subscribe to the event:
3939 .. code-block:: javascript
3946 * args[0] = movedCollectionElementIdentifier
3947 * args[1] = previousCollectionElementIdentifier
3948 * args[2] = nextCollectionElementIdentifier
3949 * args[3] = collectionName
3952 getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', function(topic, args) {
3956 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-editor-insert-perform:
3958 view/inspector/editor/insert/perform
3959 ++++++++++++++++++++++++++++++++++++
3961 The methods ``getFormEditorApp().getViewModel().renderInspectorEditors()`` (to
3962 render all ``inspector editors`` for a form element) and ``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``
3963 (to render the ``inspector editors`` for a validator/ finisher) call this event
3964 at the end. Strictly speaking, the ``Inspector`` component in the method
3965 ``_renderEditorDispatcher()`` calls this event.
3966 Each ``inspector editor`` has the property :ref:`templateName <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.templatename>`,
3967 which gives the ``form editor`` two pieces of information. On the one hand the
3968 ``templateName`` must match with a key within the :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
3969 The ``form editor`` can consequently load a corresponding inline HTML template
3970 for the ``inspector editor``. On the other hand, the ``Inspector`` component
3971 must be told which JavaScript code should be executed for the
3972 ``inspector editor``. For the ``inspector editors`` delivered with EXT:form,
3973 this occurs within the method ``_renderEditorDispatcher()``.
3974 An existing hard-coded list of known ``inspector editors`` determines, by means
3975 of the property ``templateName``, which corresponding JavaScript method should
3976 be executed for the ``inspector editor``. At the end, the event
3977 ``view/inspector/editor/insert/perform`` is called. If you wish to implement
3978 your own ``inspector editor``, you can use this event to execute in
3979 :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
3980 the corresponding JavaScript code, with the help of the property
3984 Subscribe to the event:
3986 .. code-block:: javascript
3993 * args[0] = editorConfiguration
3994 * args[1] = editorHtml
3995 * args[2] = collectionElementIdentifier
3996 * args[3] = collectionName
3999 getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
4003 A simple example that registers a custom ``inspector editor`` called 'Inspector-MyCustomInspectorEditor' and adds it to text form elements:
4005 .. code-block:: yaml
4013 dynamicRequireJsModules:
4014 additionalViewModelModules:
4015 - 'TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel'
4016 formEditorFluidConfiguration:
4018 100: 'EXT:my_site_package/Resources/Private/Backend/Partials/FormEditor/'
4020 Inspector-MyCustomInspectorEditor: 'Inspector/MyCustomInspectorEditor'
4021 formElementsDefinition:
4026 templateName: 'Inspector-MyCustomInspectorEditor'
4030 .. code-block:: javascript
4031 :emphasize-lines: 107-116
4034 * Module: TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel
4037 'TYPO3/CMS/Form/Backend/FormEditor/Helper'
4038 ], function($, Helper) {
4041 return (function($, Helper) {
4048 var _formEditorApp = null;
4055 function getFormEditorApp() {
4056 return _formEditorApp;
4064 function getPublisherSubscriber() {
4065 return getFormEditorApp().getPublisherSubscriber();
4073 function getUtility() {
4074 return getFormEditorApp().getUtility();
4083 function getHelper() {
4092 function getCurrentlySelectedFormElement() {
4093 return getFormEditorApp().getCurrentlySelectedFormElement();
4100 * @param string message
4101 * @param int messageCode
4104 function assert(test, message, messageCode) {
4105 return getFormEditorApp().assert(test, message, messageCode);
4112 * @throws 1491643380
4114 function _helperSetup() {
4115 assert('function' === $.type(Helper.bootstrap),
4116 'The view model helper does not implement the method "bootstrap"',
4119 Helper.bootstrap(getFormEditorApp());
4127 function _subscribeEvents() {
4133 * args[0] = editorConfiguration
4134 * args[1] = editorHtml
4135 * args[2] = collectionElementIdentifier
4136 * args[3] = collectionName
4139 getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
4140 if (args[0]['templateName'] === 'Inspector-MyCustomInspectorEditor') {
4141 renderMyCustomInspectorEditor(
4154 * @param object editorConfiguration
4155 * @param object editorHtml
4156 * @param string collectionElementIdentifier
4157 * @param string collectionName
4160 function renderMyCustomInspectorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
4167 * @param object formEditorApp
4170 function bootstrap(formEditorApp) {
4171 _formEditorApp = formEditorApp;
4177 * Publish the public methods.
4178 * Implements the "Revealing Module Pattern".
4181 bootstrap: bootstrap
4187 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-removecollectionelement-perform:
4189 view/inspector/removeCollectionElement/perform
4190 ++++++++++++++++++++++++++++++++++++++++++++++
4192 The ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
4193 calls this event, if the checkbox is deselected. EXT:form uses this event to
4194 remove the configured required validator ('NotEmpty') from the ``form
4195 definition`` through the method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
4198 Subscribe to the event:
4200 .. code-block:: javascript
4207 * args[0] = collectionElementIdentifier
4208 * args[1] = collectionName
4209 * args[2] = formElement
4212 getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', function(topic, args) {
4216 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-close-perform:
4218 view/modal/close/perform
4219 ++++++++++++++++++++++++
4221 If you try to close the ``form editor`` with unsaved content, a dialog box
4222 appears, asking whether you really wish to close it. If you confirm it, this
4223 event is called in the ``check box`` component. EXT:form uses this event to
4224 close the ``form editor`` and return to the ``form manager``.
4227 Subscribe to the event:
4229 .. code-block:: javascript
4238 getPublisherSubscriber().subscribe('view/modal/close/perform', function(topic, args) {
4242 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removecollectionelement-perform:
4244 view/modal/removeCollectionElement/perform
4245 ++++++++++++++++++++++++++++++++++++++++++
4247 If you try to remove a validator/ finisher by clicking the remove icon, a
4248 dialog box appears, asking you to confirm this action. If confirmed, this event
4249 is called in the ``check box`` component. EXT:form uses this event to remove
4250 the validator/ finisher from the ``form definition`` through the method
4251 ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
4254 Subscribe to the event:
4256 .. code-block:: javascript
4263 * args[0] = collectionElementIdentifier
4264 * args[1] = collectionName
4265 * args[2] = formElement
4268 getPublisherSubscriber().subscribe('view/modal/removeCollectionElement/perform', function(topic, args) {
4272 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removeformelement-perform:
4274 view/modal/removeFormElement/perform
4275 ++++++++++++++++++++++++++++++++++++
4277 If you try to remove a form element by clicking the remove icon, a dialog box
4278 appears, asking you to confirm this action. If confirmed, this event is called
4279 in the ``check box`` component. EXT:form uses this event to remove the form
4280 element from the ``form definition`` via the method ``getFormEditorApp().getViewModel().removeFormElement()``.
4283 Subscribe to the event:
4285 .. code-block:: javascript
4292 * args[0] = formElement
4295 getPublisherSubscriber().subscribe('view/modal/removeFormElement/perform', function(topic, args) {
4299 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-validationerrors-element-clicked:
4301 view/modal/validationErrors/element/clicked
4302 +++++++++++++++++++++++++++++++++++++++++++
4304 If a form element contains a validation error and you try to save the form, a
4305 dialog box appears, listing all form elements with validation errors. One such
4306 form element can be clicked in this dialog box. This event is called by
4307 clicking a form element in the dialog box. EXT:form uses this event to select
4308 and show this form element.
4311 Subscribe to the event:
4313 .. code-block:: javascript
4320 * args[0] = formElementIdentifierPath
4323 getPublisherSubscriber().subscribe('view/modal/validationErrors/element/clicked', function(topic, args) {
4327 .. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationnext-clicked:
4329 view/paginationNext/clicked
4330 +++++++++++++++++++++++++++
4332 This event is called if the 'pagination next' button in the ``Stage``
4333 component's header section is clicked. EXT:form uses this event to render the
4334 next page of the form.
4337 Subscribe to the event:
4339 .. code-block:: javascript
4348 getPublisherSubscriber().subscribe('view/paginationNext/clicked', function(topic, args) {
4352 .. _apireference-formeditor-basicjavascriptconcepts-events-view-paginationprevious-clicked:
4354 view/paginationPrevious/clicked
4355 +++++++++++++++++++++++++++++++
4357 This event is called, if the 'pagination previous' button in the ``Stage``
4358 component's header section is clicked. EXT:form uses this event to render the
4359 previous page of the form.
4362 Subscribe to the event:
4364 .. code-block:: javascript
4373 getPublisherSubscriber().subscribe('view/paginationPrevious/clicked', function(topic, args) {
4377 .. _apireference-formeditor-basicjavascriptconcepts-events-view-ready:
4382 EXT:form makes it possible to load :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
4383 If all modules are loaded, the view-model method ``_loadAdditionalModules``
4384 calls this event. EXT:form uses this event to remove the preloader icon and
4385 finally initialize the ``form editor``.
4388 Subscribe to the event:
4390 .. code-block:: javascript
4399 getPublisherSubscriber().subscribe('view/ready', function(topic, args) {
4403 .. _apireference-formeditor-basicjavascriptconcepts-events-view-redobutton-clicked:
4405 view/redoButton/clicked
4406 +++++++++++++++++++++++
4408 This event is called if the redo button in the ``form editor`` header is
4409 clicked. The addition/ deletion and movement of form elements and property
4410 collection elements (validators/ finishers) is saved in an internal stack in
4411 order to reset the undo/ redo functionality. EXT:form uses this event to reset
4412 this stack to the previous state.
4415 Subscribe to the event:
4417 .. code-block:: javascript
4426 getPublisherSubscriber().subscribe('view/redoButton/clicked', function(topic, args) {
4430 .. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-button-newelement-clicked:
4432 view/stage/abstract/button/newElement/clicked
4433 +++++++++++++++++++++++++++++++++++++++++++++
4435 This event is called if the "Create new element" button at the end of the
4436 ``Stage`` component in the ``abstract view`` mode is clicked. EXT:form uses
4437 this event to display the "new element" dialog box.
4440 Subscribe to the event:
4442 .. code-block:: javascript
4449 * args[0] = targetEvent
4450 * args[1] = configuration
4453 getPublisherSubscriber().subscribe('view/stage/abstract/button/newElement/clicked', function(topic, args) {
4457 .. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-change:
4459 view/stage/abstract/dnd/change
4460 ++++++++++++++++++++++++++++++
4462 EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
4463 drop functionality. The 'change' event from 'jquery.mjs.nestedSortable' calls
4464 the ``view/stage/abstract/dnd/change`` event in the ``Stage`` component in the
4465 ``abstract view`` mode if form elements are sorted. EXT:form uses this event to
4466 set various CSS classes during the drag-and-drop process.
4469 Subscribe to the event:
4471 .. code-block:: javascript
4478 * args[0] = placeholderDomElement
4479 * args[1] = parentFormElementIdentifierPath
4480 * args[2] = enclosingCompositeFormElement
4483 getPublisherSubscriber().subscribe('view/stage/abstract/dnd/change', function(topic, args) {
4487 .. _apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-dnd-start:
4489 view/stage/abstract/dnd/start
4490 +++++++++++++++++++++++++++++
4492 EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
4493 drop functionality. The 'start' event from 'jquery.mjs.nestedSortable' calls
4494 the ``view/stage/abstract/dnd/start`` event in the ``Stage`` component in the
4495 ``abstract view`` mode if form elements are sorted. EXT:form uses this event to
4496 set various CSS classes at the start of the drag-and-drop process.
4499 Subscribe to the event:
4501 .. code-block:: javascript