[BUGFIX] Registration of multiple additional view models
[Packages/TYPO3.CMS.git] / typo3 / sysext / form / Documentation / ApiReference / Index.rst
1 .. include:: ../Includes.txt
2
3
4 .. _apireference:
5
6 =============
7 API Reference
8 =============
9
10 This chapter is a complete reference of the API of the form framework. It
11 mainly addresses your concerns as a developer.
12
13
14 .. _apireference-frontendrendering:
15
16 Frontend rendering
17 ==================
18
19
20 .. _apireference-frontendrendering-fluidformrenderer:
21
22 TYPO3\\CMS\\Form\\Domain\\Renderer\\FluidFormRenderer
23 -----------------------------------------------------
24
25
26 .. _apireference-frontendrendering-fluidformrenderer-options:
27
28 Options
29 ^^^^^^^
30
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.
33
34 All rendering options are retrieved from the ``FormDefinition``, using the ``TYPO3\CMS\Form\Domain\Model\FormDefinition::getRenderingOptions()`` method.
35
36
37 .. _apireference-frontendrendering-fluidformrenderer-options-templaterootpaths:
38
39 templateRootPaths
40 +++++++++++++++++
41
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>``.
45
46 For example:
47
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
51
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``.
53
54 .. code-block:: yaml
55
56    TYPO3:
57      CMS:
58        Form:
59          prototypes:
60            standard:
61              formElementsDefinition:
62                Form:
63                  renderingOptions:
64                    templateRootPaths:
65                      10: 'EXT:form/Resources/Private/Frontend/Templates/'
66
67
68 .. _apireference-frontendrendering-fluidformrenderer-options-layoutrootpaths:
69
70 layoutRootPaths
71 +++++++++++++++
72
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.
75
76 .. code-block:: yaml
77
78    TYPO3:
79      CMS:
80        Form:
81          prototypes:
82            standard:
83              formElementsDefinition:
84                Form:
85                  renderingOptions:
86                    layoutRootPaths:
87                      10: 'EXT:form/Resources/Private/Frontend/Layouts/'
88
89
90 .. _apireference-frontendrendering-fluidformrenderer-options-partialrootpaths:
91
92 partialRootPaths
93 ++++++++++++++++
94
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.
97
98 Within this paths, fluid will search for a file which is named like the ``<formElementTypeIdentifier>``.
99
100 For example:
101
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
105
106 There is a setting available to set a custom partial name. Please read the section :ref:`templateName<apireference-frontendrendering-fluidformrenderer-options-templatename>`.
107
108 .. code-block:: yaml
109
110    TYPO3:
111      CMS:
112        Form:
113          prototypes:
114            standard:
115              formElementsDefinition:
116                Form:
117                  renderingOptions:
118                    partialRootPaths:
119                      10: 'EXT:form/Resources/Private/Frontend/Partials/'
120
121
122 .. _apireference-frontendrendering-fluidformrenderer-options-templatename:
123
124 templateName
125 ++++++++++++
126
127 By default, the renderable type will be taken as the name for the partial.
128
129 For example:
130
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
134
135 Set ``templateName`` to define a custom name which should be used instead.
136
137 For example:
138
139 $renderable->getTemplateName() == 'Text'
140 $renderable->getType() = Foo
141 Expected partial file: EXT:form/Resources/Private/Frontend/Partials/Text.html
142
143 .. code-block:: yaml
144
145    TYPO3:
146      CMS:
147        Form:
148          prototypes:
149            standard:
150              formElementsDefinition:
151                Foo:
152                  renderingOptions:
153                    templateName: 'Text'
154
155
156 .. _apireference-frontendrendering-renderviewHelper:
157
158 "render" viewHelper
159 -------------------
160
161
162 .. _apireference-frontendrendering-renderviewHelper-arguments:
163
164 Arguments
165 ^^^^^^^^^
166
167
168 .. _apireference-frontendrendering-renderviewHelper-factoryclass:
169
170 factoryClass
171 ++++++++++++
172
173 A class name of a ``FormFactory``.
174 This factory is used to create the ``TYPO3\CMS\Form\Domain\Model\FormDefinition`` which is the ``form definition`` Domain Model.
175 If no ``factoryClass`` argument is passed, the factory supplied by EXT:form ``TYPO3\CMS\Form\ Domain\Factory\ArrayFormFactory`` is used.
176 Another factory class is required if the form is to be generated programmatically.
177 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.
178 This then renders the form.
179
180 .. code-block:: html
181
182    <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
183
184
185 .. _apireference-frontendrendering-renderviewHelper-persistenceidentifier:
186
187 persistenceIdentifier
188 +++++++++++++++++++++
189
190 The ``form definition`` to be found under ``persistenceIdentifier``.
191 The PersistenceManager now loads the ``form definition`` which is found under ``persistenceIdentifier`` and passes this configuration to the ``factoryClass``.
192 In this case, the ``factoryClass`` will be given an empty configuration array (if ``overrideConfiguration`` is not specified).
193
194 .. code-block:: html
195
196    <formvh:render persistenceIdentifier="EXT:my_site_package/Resources/Private/Forms/SimpleContactForm.yaml" />
197
198
199 .. _apireference-frontendrendering-renderviewHelper-overrideconfiguration:
200
201 overrideConfiguration
202 +++++++++++++++++++++
203
204 A configuration to be superimposed can be entered here.
205 If a ``persistenceIdentifier`` is specified, the ``form definition`` which is found under ``persistenceIdentifier`` is loaded.
206 This configuration is then superimposed with ``overrideConfiguration``. This configuration is then passed to the ``factoryClass``.
207 If no ``persistenceIdentifier`` is specified, ``overrideConfiguration`` is passed directly to the ``factoryClass``.
208 This way a configuration can be given to a ``factoryClass`` implementation.
209
210
211 .. _apireference-frontendrendering-renderviewHelper-prototypename:
212
213 prototypeName
214 +++++++++++++
215
216 The name of the prototype, on which basis the ``factoryClass`` should create the form.
217 If nothing is specified, the configuration (``form definition`` or ``overrideConfiguration``) is searched for the prototy name.
218 If no specification exists, the standard prototype ``standard`` is used.
219
220
221 .. _apireference-frontendrendering-programmatically:
222
223 Build forms programmatically
224 ----------------------------
225
226 Implement a ``FormFactory`` and build the form::
227
228    <?php
229    declare(strict_types = 1);
230    namespace VENDOR\MySitePackage\Domain\Factory;
231
232    use TYPO3\CMS\Core\Utility\GeneralUtility;
233    use TYPO3\CMS\Extbase\Object\ObjectManager;
234    use TYPO3\CMS\Extbase\Validation\Validator\NotEmptyValidator;
235    use TYPO3\CMS\Extbase\Validation\Validator\StringLengthValidator;
236    use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
237    use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
238    use TYPO3\CMS\Form\Domain\Model\FormDefinition;
239
240    class CustomFormFactory extends AbstractFormFactory
241    {
242
243        /**
244         * Build a FormDefinition.
245         * This example build a FormDefinition manually,
246         * so $configuration and $prototypeName are unused.
247         *
248         * @param array $configuration
249         * @param string $prototypeName
250         * @return FormDefinition
251         */
252        public function build(array $configuration, string $prototypeName = null): FormDefinition
253        {
254            $prototypeName = 'standard';
255            $configurationService = GeneralUtility::makeInstance(ObjectManager::class)->get(ConfigurationService::class);
256            $prototypeConfiguration = $configurationService->getPrototypeConfiguration($prototypeName);
257
258            $form = GeneralUtility::makeInstance(ObjectManager::class)->get(FormDefinition::class, 'MyCustomForm', $prototypeConfiguration);
259            $form->setRenderingOption('controllerAction', 'index');
260
261            $page1 = $form->createPage('page1');
262            $name = $page1->createElement('name', 'Text');
263            $name->setLabel('Name');
264            $name->addValidator(GeneralUtility::makeInstance(ObjectManager::class)->get(NotEmptyValidator::class));
265
266            $page2 = $form->createPage('page2');
267            $message = $page2->createElement('message', 'Textarea');
268            $message->setLabel('Message');
269            $message->addValidator(GeneralUtility::makeInstance(ObjectManager::class)->get(StringLengthValidator::class, ['minimum' => 5, 'maximum' => 20]));
270
271            $form->createFinisher('EmailToSender', [
272                'subject' => 'Hello',
273                'recipientAddress' => 'foo@example.com',
274                'senderAddress' => 'bar@example.com',
275            ]);
276
277            $this->triggerFormBuildingFinished($form);
278            return $form;
279        }
280    }
281
282
283 Use this form within your fluid template.
284
285 .. code-block:: html
286
287    <formvh:render factoryClass="VENDOR\MySitePackage\Domain\Factory\CustomFormFactory" />
288
289
290 .. _apireference-frontendrendering-programmatically-commonapimethods:
291
292 Common API Methods
293 ^^^^^^^^^^^^^^^^^^
294
295
296 .. _apireference-frontendrendering-programmatically-commonapimethods-createpage:
297
298 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createPage()
299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
300
301 Create a page with the given $identifier and attach this page to the form.
302
303 - Create Page object based on the given $typeName
304 - set defaults inside the Page object
305 - attach Page object to this form
306 - return the newly created Page object
307
308 Signature::
309
310    public function createPage(string $identifier, string $typeName = 'Page'): Page;
311
312
313 .. _apireference-frontendrendering-programmatically-commonapimethods-createfinisher:
314
315 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition::createFinisher()
316 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
317
318 Create a finisher with the given $identifier and given $options and attach this finisher to the form.
319
320 Signature::
321
322    public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
323
324
325 .. _apireference-frontendrendering-programmatically-commonapimethods-page-createelement:
326
327 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page::createElement()
328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
329
330 Create a form element with the given $identifier and attach it to the page.
331
332 - Create Form Element object based on the given $typeName
333 - set defaults inside the Form Element (based on the parent form's field defaults)
334 - attach Form Element to the Page
335 - return the newly created Form Element object
336
337 Signature::
338
339    public function createElement(string $identifier, string $typeName): FormElementInterface;
340
341
342 .. _apireference-frontendrendering-programmatically-commonapimethods-section-createelement:
343
344 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section::createElement()
345 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
346
347 Create a form element with the given $identifier and attach it to the section.
348
349 - Create Form Element object based on the given $typeName
350 - set defaults inside the Form Element (based on the parent form's field defaults)
351 - attach Form Element to the Section
352 - return the newly created Form Element object
353
354 Signature::
355
356    public function createElement(string $identifier, string $typeName): FormElementInterface;
357
358
359 .. _apireference-frontendrendering-programmatically-commonapimethods-abstractrenderable-createvalidator:
360
361 TYPO3\\CMS\\Form\\Domain\\Model\\Renderable\\AbstractFormElement::createValidator()
362 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
363
364 Create a validator for the element.
365 Mainly possible for
366
367 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
368 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
369 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
370 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
371
372 Signature::
373
374    public function createValidator(string $validatorIdentifier, array $options = []);
375
376
377 .. _apireference-frontendrendering-programmatically-commonapimethods-initializeformelement:
378
379 initializeFormElement()
380 +++++++++++++++++++++++
381
382 Will be called as soon as the element is added to a form.
383 Possible for
384
385 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
386 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
387 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
388 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
389 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
390
391 Signature::
392
393    public function initializeFormElement();
394
395
396 You can use this method to prefill form element data for example from database tables.
397 All the classes you can see above extends from the ``TYPO3\CMS\Form\Domain\Model\FormElement\AbstractFormElement``.
398 ``AbstractFormElement`` implements this method like this::
399
400    public function initializeFormElement()
401    {
402        if (
403            isset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
404            && is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'])
405        ) {
406            foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'] as $className) {
407                $hookObj = GeneralUtility::makeInstance($className);
408                if (method_exists($hookObj, 'initializeFormElement')) {
409                    $hookObj->initializeFormElement(
410                        $this
411                    );
412                }
413            }
414        }
415    }
416
417 If you extend you custom implementation from ``AbstractFormElement`` (and you should do this),
418 it enables you to override the 'initializeFormElement' method within your custom implementation class.
419 If you do not call the parents 'initializeFormElement' then no hook will be thrown.
420
421 If your use case for a custom form element implementation means that you only want to initialize you form element
422 programmatically (e.g to get databasedata) and no other special things are to do, you might prefer the hook.
423 You only need a class which connects to this hook. Then detect the form element you wish to initialize.
424
425
426 .. _apireference-frontendrendering-programmatically-apimethods:
427
428 API Methods
429 ^^^^^^^^^^^
430
431
432 .. _apireference-frontendrendering-programmatically-apimethods-formruntime:
433
434 TYPO3\\CMS\\Form\\Domain\\Model\\FormRuntime
435 ++++++++++++++++++++++++++++++++++++++++++++
436
437
438 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-overridecurrentpage:
439
440 overrideCurrentPage()
441 '''''''''''''''''''''
442
443 Override the current page taken from the request, rendering the page with index $pageIndex instead.
444 This is typically not needed in production code.
445 You might prefer the hook :ref:`afterInitializeCurrentPage <apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage>`
446
447 Signature::
448
449    public function overrideCurrentPage(int $pageIndex);
450
451 Example::
452
453    $form = $formDefinition->bind($this->request, $this->response);
454    $form->overrideCurrentPage($pageIndex);
455
456
457 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-render:
458
459 render()
460 ''''''''
461
462 Render the form.
463
464 Signature::
465
466    public function render();
467
468
469 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getidentifier:
470 .. include:: RootRenderableInterface/getIdentifier.rst
471
472 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrequest:
473
474 getRequest()
475 ''''''''''''
476
477 Get the request this object is bound to.
478 This is mostly relevant inside Finishers, where you f.e. want to redirect the user to another page.
479
480 Signature::
481
482    public function getRequest(): Request;
483
484
485 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getresponse:
486
487 getResponse()
488 '''''''''''''
489
490 Get the response this object is bound to.
491 This is mostly relevant inside Finishers, where you f.e. want to set response headers or output content.
492
493 Signature::
494
495    public function getResponse(): Response;
496
497
498 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getcurrentpage:
499
500 getCurrentPage()
501 ''''''''''''''''
502
503 Returns the currently selected page.
504
505 Signature::
506
507    public function getCurrentPage(): Page;
508
509
510 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpreviouspage:
511
512 getPreviousPage()
513 '''''''''''''''''
514
515 Returns the previous page of the currently selected one or NULL if there is no previous page.
516
517 Signature::
518
519    public function getPreviousPage();
520
521
522 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getnextpage:
523
524 getNextPage()
525 '''''''''''''
526
527 Returns the next page of the currently selected one or NULL if there is no next page.
528
529 Signature::
530
531    public function getNextPage();
532
533
534 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettype:
535 .. include:: RootRenderableInterface/getType.rst
536
537
538 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getelementvalue:
539
540 getElementValue()
541 '''''''''''''''''
542
543 Returns the value of the specified element.
544
545 Signature::
546
547    public function getElementValue(string $identifier);
548
549
550 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getpages:
551
552 getPages()
553 ''''''''''
554
555 Return the form's pages in the correct order.
556
557 Signature::
558
559    public function getPages(): array;
560
561
562 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrenderingoptions:
563 .. include:: RootRenderableInterface/getRenderingOptions.rst
564
565 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getrendererclassname:
566 .. include:: RootRenderableInterface/getRendererClassName.rst
567
568 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getlabel:
569 .. include:: RootRenderableInterface/getLabel.rst
570
571 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-gettemplatename:
572 .. include:: RenderableInterface/getTemplateName.rst
573
574 .. _apireference-frontendrendering-programmatically-apimethods-formruntime-getformdefinition:
575
576 getFormDefinition()
577 '''''''''''''''''''
578
579 Get the underlying form definition from the runtime.
580
581 Signature::
582
583    public function getFormDefinition(): FormDefinition;
584
585
586 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition:
587
588 TYPO3\\CMS\\Form\\Domain\\Model\\FormDefinition
589 +++++++++++++++++++++++++++++++++++++++++++++++
590
591 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addpage:
592
593 addPage()
594 '''''''''
595
596 Add a new page at the end of the form.
597 Instead of this method, you should use ``createPage`` instead.
598
599 Signature::
600
601    public function addPage(Page $page);
602
603
604 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createpage:
605
606 createPage()
607 ''''''''''''
608
609 Create a page with the given $identifier and attach this page to the form.
610
611 - Create Page object based on the given $typeName
612 - set defaults inside the Page object
613 - attach Page object to this form
614 - return the newly created Page object
615
616 Signature::
617
618    public function createPage(string $identifier, string $typeName = 'Page'): Page;
619
620
621 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpages:
622
623 getPages()
624 ''''''''''
625
626 Return the form's pages in the correct order.
627
628 Signature::
629
630    public function getPages(): array;
631
632
633 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-haspagewithindex:
634
635 hasPageWithIndex()
636 ''''''''''''''''''
637
638 Check whether a page with the given $index exists.
639
640 Signature::
641
642    public function hasPageWithIndex(int $index): bool;
643
644
645 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getpagebyindex:
646
647 getPageByIndex()
648 ''''''''''''''''
649
650 Get the page with the passed index. The first page has index zero.
651 If page at $index does not exist, an exception is thrown.
652
653 Signature::
654
655    public function getPageByIndex(int $index);
656
657
658 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addfinisher:
659
660 addFinisher()
661 '''''''''''''
662
663 Adds the specified finisher to the form.
664 Instead of this method, you should use ``createFinisher`` instead.
665
666 Signature::
667
668    public function addFinisher(FinisherInterface $finisher);
669
670
671 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-createfinisher:
672
673 createFinisher()
674 ''''''''''''''''
675
676 Create a finisher with the given $identifier and given $options and attach this finisher to the form.
677
678 Signature::
679
680    public function createFinisher(string $finisherIdentifier, array $options = []): FinisherInterface;
681
682
683 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getfinishers:
684
685 getFinishers()
686 ''''''''''''''
687
688 Gets all finishers of the form.
689
690 Signature::
691
692    public function getFinishers(): array;
693
694
695 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getelementbyidentifier:
696
697 getElementByIdentifier()
698 ''''''''''''''''''''''''
699
700 Get a form element by its identifier.
701 If identifier does not exist, returns NULL.
702
703 Signature::
704
705    public function getElementByIdentifier(string $elementIdentifier);
706
707
708 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-movepageafter:
709
710 movePageAfter()
711 '''''''''''''''
712
713 Move $pageToMove after $referencePage.
714
715 Signature::
716
717    public function movePageAfter(Page $pageToMove, Page $referencePage);
718
719
720 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-removepage:
721
722 removePage()
723 ''''''''''''
724
725 Remove $pageToRemove from the form.
726
727 Signature::
728
729    public function removePage(Page $pageToRemove);
730
731
732 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-bind:
733
734 bind()
735 ''''''
736
737 Bind the current request and response to this form instance, effectively creating a new "instance" of the Form.
738
739 Signature::
740
741    public function bind(Request $request, Response $response): FormRuntime;
742
743
744 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getprocessingrule:
745
746 getProcessingRule()
747 '''''''''''''''''''
748
749 Get the processing rule which contains information for property mappings and validations.
750
751 Signature::
752
753    public function getProcessingRule(string $propertyPath): ProcessingRule;
754
755
756 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettype:
757 .. include:: RootRenderableInterface/getType.rst
758
759 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getidentifier:
760 .. include:: RootRenderableInterface/getIdentifier.rst
761
762 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setidentifier:
763 .. include:: AbstractRenderable/setIdentifier.rst
764
765 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setoptions:
766 .. include:: AbstractRenderable/setOptions.rst
767
768 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-addvalidator:
769 .. include:: FormElementInterface/addValidator.rst
770
771 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setdatatype:
772 .. include:: FormElementInterface/setDataType.rst
773
774 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrendererclassname:
775 .. include:: RootRenderableInterface/getRendererClassName.rst
776
777 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrendererclassname:
778
779 setRendererClassName()
780 ''''''''''''''''''''''
781
782 Set the renderer class name.
783
784 Signature::
785
786    public function setRendererClassName(string $rendererClassName);
787
788
789 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrenderingoptions:
790 .. include:: RootRenderableInterface/getRenderingOptions.rst
791
792 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setrenderingoption:
793 .. include:: FormElementInterface/setRenderingOption.rst
794
795 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getparentrenderable:
796 .. include:: RenderableInterface/getParentRenderable.rst
797
798 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setparentrenderable:
799 .. include:: RenderableInterface/setParentRenderable.rst
800
801 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getrootform:
802 .. include:: AbstractRenderable/getRootForm.rst
803
804 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-getlabel:
805 .. include:: RootRenderableInterface/getLabel.rst
806
807 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-setlabel:
808 .. include:: AbstractRenderable/setLabel.rst
809
810 .. _apireference-frontendrendering-programmatically-apimethods-formdefinition-gettemplatename:
811 .. include:: RenderableInterface/getTemplateName.rst
812
813
814 .. _apireference-frontendrendering-programmatically-apimethods-page:
815
816 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Page
817 +++++++++++++++++++++++++++++++++++++++++++++++++++
818
819 .. _apireference-frontendrendering-programmatically-apimethods-page-getelements:
820 .. include:: AbstractSection/getElements.rst
821
822 .. _apireference-frontendrendering-programmatically-apimethods-page-getelementsrecursively:
823 .. include:: AbstractSection/getElementsRecursively.rst
824
825 .. _apireference-frontendrendering-programmatically-apimethods-page-addelement:
826 .. include:: AbstractSection/addElement.rst
827
828 .. _apireference-frontendrendering-programmatically-apimethods-page-createelement:
829
830 createElement()
831 '''''''''''''''
832
833 Create a form element with the given $identifier and attach it to the page.
834
835 - Create Form Element object based on the given $typeName
836 - set defaults inside the Form Element (based on the parent form's field defaults)
837 - attach Form Element to the Page
838 - return the newly created Form Element object
839
840 Signature::
841
842    public function createElement(string $identifier, string $typeName): FormElementInterface;
843
844
845 .. _apireference-frontendrendering-programmatically-apimethods-page-moveelementbefore:
846 .. include:: AbstractSection/moveElementBefore.rst
847
848 .. _apireference-frontendrendering-programmatically-apimethods-page-moveelementafter:
849 .. include:: AbstractSection/moveElementAfter.rst
850
851 .. _apireference-frontendrendering-programmatically-apimethods-page-removeelement:
852 .. include:: AbstractSection/removeElement.rst
853
854 .. _apireference-frontendrendering-programmatically-apimethods-page-gettype:
855 .. include:: RootRenderableInterface/getType.rst
856
857 .. _apireference-frontendrendering-programmatically-apimethods-page-getidentifier:
858 .. include:: RootRenderableInterface/getIdentifier.rst
859
860 .. _apireference-frontendrendering-programmatically-apimethods-page-setidentifier:
861 .. include:: AbstractRenderable/setIdentifier.rst
862
863 .. _apireference-frontendrendering-programmatically-apimethods-page-setoptions:
864 .. include:: AbstractRenderable/setOptions.rst
865
866 .. _apireference-frontendrendering-programmatically-apimethods-page-addvalidator:
867 .. include:: FormElementInterface/addValidator.rst
868
869 .. _apireference-frontendrendering-programmatically-apimethods-page-createvalidator:
870 .. include:: FormElementInterface/createValidator.rst
871
872 .. _apireference-frontendrendering-programmatically-apimethods-page-setdatatype:
873 .. include:: FormElementInterface/setDataType.rst
874
875 .. _apireference-frontendrendering-programmatically-apimethods-page-getrendererclassname:
876 .. include:: RootRenderableInterface/getRendererClassName.rst
877
878 .. _apireference-frontendrendering-programmatically-apimethods-page-getrenderingoptions:
879 .. include:: RootRenderableInterface/getRenderingOptions.rst
880
881 .. _apireference-frontendrendering-programmatically-apimethods-page-setrenderingoption:
882 .. include:: FormElementInterface/setRenderingOption.rst
883
884 .. _apireference-frontendrendering-programmatically-apimethods-page-getparentrenderable:
885 .. include:: RenderableInterface/getParentRenderable.rst
886
887 .. _apireference-frontendrendering-programmatically-apimethods-page-setparentrenderable:
888 .. include:: RenderableInterface/setParentRenderable.rst
889
890 .. _apireference-frontendrendering-programmatically-apimethods-page-getrootform:
891 .. include:: AbstractRenderable/getRootForm.rst
892
893 .. _apireference-frontendrendering-programmatically-apimethods-page-getlabel:
894 .. include:: RootRenderableInterface/getLabel.rst
895
896 .. _apireference-frontendrendering-programmatically-apimethods-page-setlabel:
897 .. include:: AbstractRenderable/setLabel.rst
898
899 .. _apireference-frontendrendering-programmatically-apimethods-page-gettemplatename:
900 .. include:: RenderableInterface/getTemplateName.rst
901
902
903 .. _apireference-frontendrendering-programmatically-apimethods-section:
904
905 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\Section
906 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
907
908 .. _apireference-frontendrendering-programmatically-apimethods-section-initializeformelement:
909 .. include:: FormElementInterface/initializeFormElement.rst
910
911 .. _apireference-frontendrendering-programmatically-apimethods-section-getuniqueidentifier:
912 .. include:: FormElementInterface/getUniqueIdentifier.rst
913
914 .. _apireference-frontendrendering-programmatically-apimethods-section-setproperty:
915 .. include:: FormElementInterface/setProperty.rst
916
917 .. _apireference-frontendrendering-programmatically-apimethods-section-getproperties:
918 .. include:: FormElementInterface/getProperties.rst
919
920 .. _apireference-frontendrendering-programmatically-apimethods-section-isrequired:
921 .. include:: FormElementInterface/isRequired.rst
922
923 .. _apireference-frontendrendering-programmatically-apimethods-section-getelements:
924 .. include:: AbstractSection/getElements.rst
925
926 .. _apireference-frontendrendering-programmatically-apimethods-section-getelementsrecursively:
927 .. include:: AbstractSection/getElementsRecursively.rst
928
929 .. _apireference-frontendrendering-programmatically-apimethods-section-addelement:
930 .. include:: AbstractSection/addElement.rst
931
932 .. _apireference-frontendrendering-programmatically-apimethods-section-createelement:
933
934 createElement()
935 '''''''''''''''
936
937 Create a form element with the given $identifier and attach it to the section.
938
939 - Create Form Element object based on the given $typeName
940 - set defaults inside the Form Element (based on the parent form's field defaults)
941 - attach Form Element to the Section
942 - return the newly created Form Element object
943
944 Signature::
945
946    public function createElement(string $identifier, string $typeName): FormElementInterface;
947
948
949 .. _apireference-frontendrendering-programmatically-apimethods-section-moveelementbefore:
950 .. include:: AbstractSection/moveElementBefore.rst
951
952 .. _apireference-frontendrendering-programmatically-apimethods-section-moveelementafter:
953 .. include:: AbstractSection/moveElementAfter.rst
954
955 .. _apireference-frontendrendering-programmatically-apimethods-section-removeelement:
956 .. include:: AbstractSection/removeElement.rst
957
958 .. _apireference-frontendrendering-programmatically-apimethods-section-gettype:
959 .. include:: RootRenderableInterface/getType.rst
960
961 .. _apireference-frontendrendering-programmatically-apimethods-section-getidentifier:
962 .. include:: RootRenderableInterface/getIdentifier.rst
963
964 .. _apireference-frontendrendering-programmatically-apimethods-section-setidentifier:
965 .. include:: AbstractRenderable/setIdentifier.rst
966
967 .. _apireference-frontendrendering-programmatically-apimethods-section-setoptions:
968 .. include:: AbstractRenderable/setOptions.rst
969
970 .. _apireference-frontendrendering-programmatically-apimethods-section-addvalidator:
971 .. include:: FormElementInterface/addValidator.rst
972
973 .. _apireference-frontendrendering-programmatically-apimethods-section-createvalidator:
974 .. include:: FormElementInterface/createValidator.rst
975
976 .. _apireference-frontendrendering-programmatically-apimethods-section-setdatatype:
977 .. include:: FormElementInterface/setDataType.rst
978
979 .. _apireference-frontendrendering-programmatically-apimethods-section-getrendererclassname:
980 .. include:: RootRenderableInterface/getRendererClassName.rst
981
982 .. _apireference-frontendrendering-programmatically-apimethods-section-getrenderingoptions:
983 .. include:: RootRenderableInterface/getRenderingOptions.rst
984
985 .. _apireference-frontendrendering-programmatically-apimethods-section-setrenderingoption:
986 .. include:: FormElementInterface/setRenderingOption.rst
987
988 .. _apireference-frontendrendering-programmatically-apimethods-section-getparentrenderable:
989 .. include:: RenderableInterface/getParentRenderable.rst
990
991 .. _apireference-frontendrendering-programmatically-apimethods-section-setparentrenderable:
992 .. include:: RenderableInterface/setParentRenderable.rst
993
994 .. _apireference-frontendrendering-programmatically-apimethods-section-getrootform:
995 .. include:: AbstractRenderable/getRootForm.rst
996
997 .. _apireference-frontendrendering-programmatically-apimethods-section-getlabel:
998 .. include:: RootRenderableInterface/getLabel.rst
999
1000 .. _apireference-frontendrendering-programmatically-apimethods-section-setlabel:
1001 .. include:: AbstractRenderable/setLabel.rst
1002
1003 .. _apireference-frontendrendering-programmatically-apimethods-section-gettemplatename:
1004 .. include:: RenderableInterface/getTemplateName.rst
1005
1006
1007 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement:
1008
1009 TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AbstractFormElement
1010 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1011
1012 The following classes extends from ``AbstractFormElement`` and therefore contain the following API methods.
1013
1014 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\AdvancedPassword
1015 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\GenericFormElement
1016 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\DatePicker
1017 - TYPO3\\CMS\\Form\\Domain\\Model\\FormElements\\FileUpload
1018
1019
1020 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-initializeformelement:
1021 .. include:: FormElementInterface/initializeFormElement.rst
1022
1023 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getuniqueidentifier:
1024 .. include:: FormElementInterface/getUniqueIdentifier.rst
1025
1026 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getdefaultvalue:
1027 .. include:: FormElementInterface/getDefaultValue.rst
1028
1029 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdefaultvalue:
1030 .. include:: FormElementInterface/setDefaultValue.rst
1031
1032 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setproperty:
1033 .. include:: FormElementInterface/setProperty.rst
1034
1035 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getproperties:
1036 .. include:: FormElementInterface/getProperties.rst
1037
1038 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-isrequired:
1039 .. include:: FormElementInterface/isRequired.rst
1040
1041 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettype:
1042 .. include:: RootRenderableInterface/getType.rst
1043
1044 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getidentifier:
1045 .. include:: RootRenderableInterface/getIdentifier.rst
1046
1047 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setidentifier:
1048 .. include:: AbstractRenderable/setIdentifier.rst
1049
1050 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setoptions:
1051 .. include:: AbstractRenderable/setOptions.rst
1052
1053 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-addvalidator:
1054 .. include:: FormElementInterface/addValidator.rst
1055
1056 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-createvalidator:
1057 .. include:: FormElementInterface/createValidator.rst
1058
1059 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setdatatype:
1060 .. include:: FormElementInterface/setDataType.rst
1061
1062 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrendererclassname:
1063 .. include:: RootRenderableInterface/getRendererClassName.rst
1064
1065 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrenderingoptions:
1066 .. include:: RootRenderableInterface/getRenderingOptions.rst
1067
1068 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setrenderingoption:
1069 .. include:: FormElementInterface/setRenderingOption.rst
1070
1071 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getparentrenderable:
1072 .. include:: RenderableInterface/getParentRenderable.rst
1073
1074 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setparentrenderable:
1075 .. include:: RenderableInterface/setParentRenderable.rst
1076
1077 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getrootform:
1078 .. include:: AbstractRenderable/getRootForm.rst
1079
1080 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-getlabel:
1081 .. include:: RootRenderableInterface/getLabel.rst
1082
1083 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-setlabel:
1084 .. include:: AbstractRenderable/setLabel.rst
1085
1086 .. _apireference-frontendrendering-programmatically-apimethods-abstractformelement-gettemplatename:
1087 .. include:: RenderableInterface/getTemplateName.rst
1088
1089
1090 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher:
1091
1092 TYPO3\\CMS\\Form\\Domain\\Finishers\\AbstractFinisher
1093 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1094
1095 The following classes extends from ``AbstractFinisher`` and therefore contain the following API methods.
1096
1097 - TYPO3\\CMS\\Form\\Domain\\Finishers\\ClosureFinisher
1098 - TYPO3\\CMS\\Form\\Domain\\Finishers\\ConfirmationFinisher
1099 - TYPO3\\CMS\\Form\\Domain\\Finishers\\DeleteUploadsFinisher
1100 - TYPO3\\CMS\\Form\\Domain\\Finishers\\EmailFinisher
1101 - TYPO3\\CMS\\Form\\Domain\\Finishers\\FlashMessageFinisher
1102 - TYPO3\\CMS\\Form\\Domain\\Finishers\\RedirectFinisher
1103 - TYPO3\\CMS\\Form\\Domain\\Finishers\\SaveToDatabaseFinisher
1104
1105
1106 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-execute:
1107
1108 execute()
1109 '''''''''
1110
1111 Executes the finisher. ``AbstractFinisher::execute()`` call ``$this->executeInternal()`` at the end. Own finisher
1112 implementations which extends from  ``AbstractFinisher:`` must start their own logic within ``executeInternal()``.
1113
1114 Signature::
1115
1116    public function execute(FinisherContext $finisherContext);
1117
1118
1119 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoptions:
1120
1121 setOptions()
1122 ''''''''''''
1123
1124 Set the finisher options. Instead of directly accessing them, you should rather use ``parseOption()``.
1125
1126 Signature::
1127
1128    public function setOptions(array $options);
1129
1130
1131 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-setoption:
1132
1133 setOption()
1134 '''''''''''
1135
1136 Sets a single finisher option.
1137
1138 Signature::
1139
1140    public function setOption(string $optionName, $optionValue);
1141
1142
1143 .. _apireference-frontendrendering-programmatically-apimethods-abstractfinisher-parseoption:
1144
1145 parseOption()
1146 '''''''''''''
1147
1148 Please read :ref:`Accessing finisher options<concepts-frontendrendering-codecomponents-customfinisherimplementations-accessingoptions>`
1149
1150 Signature::
1151
1152    protected function parseOption(string $optionName);
1153
1154
1155 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext:
1156
1157 TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherContext
1158 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1159
1160 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-cancel:
1161
1162 cancel()
1163 ''''''''
1164
1165 Cancels the finisher invocation after the current finisher.
1166
1167 Signature::
1168
1169    public function cancel();
1170
1171
1172 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformruntime:
1173
1174 getFormRuntime()
1175 ''''''''''''''''
1176
1177 The Form Runtime that is associated with the current finisher.
1178
1179 Signature::
1180
1181    public function getFormRuntime(): FormRuntime;
1182
1183
1184 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getformvalues:
1185
1186 getFormValues()
1187 '''''''''''''''
1188
1189 The values of the submitted form (after validation and property mapping).
1190
1191 Signature::
1192
1193    public function getFormValues(): array;
1194
1195
1196 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getcontrollercontext:
1197
1198 getControllerContext()
1199 ''''''''''''''''''''''
1200
1201 Returns the current ControllerContext.
1202
1203 Signature::
1204
1205    public function getControllerContext(): ControllerContext;
1206
1207
1208 .. _apireference-frontendrendering-programmatically-apimethods-finishercontext-getfinishervariableprovider:
1209
1210 getFinisherVariableProvider()
1211 '''''''''''''''''''''''''''''
1212
1213 Returns the current FinisherVariableProvider.
1214
1215 Signature::
1216
1217    public function getFinisherVariableProvider(): FinisherVariableProvider;
1218
1219
1220 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider:
1221
1222 TYPO3\\CMS\\Form\\Domain\\Finishers\\FinisherVariableProvider
1223 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1224
1225 Please read :ref:`Share data between finishers<concepts-frontendrendering-codecomponents-customfinisherimplementations-finishercontext-sharedatabetweenfinishers>`
1226
1227 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-add:
1228
1229 add()
1230 '''''
1231
1232 Add a variable to the finisher variable provider.
1233 In case the value is already inside, it is silently overridden.
1234
1235 Signature::
1236
1237    public function add(string $finisherIdentifier, string $key, $value);
1238
1239
1240 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-get:
1241
1242 get()
1243 '''''
1244
1245 Gets a variable from the finisher variable provider.
1246
1247 Signature::
1248
1249    public function get(string $finisherIdentifier, string $key, $default = null);
1250
1251
1252 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-exists:
1253
1254 exists()
1255 ''''''''
1256
1257 Determine whether there is a variable stored for the given key.
1258
1259 Signature::
1260
1261    public function exists($finisherIdentifier, $key): bool;
1262
1263
1264 .. _apireference-frontendrendering-programmatically-apimethods-finishervariableprovider-remove:
1265
1266 remove()
1267 ''''''''
1268
1269 Remove a value from the finisher variable provider.
1270
1271 Signature::
1272
1273    public function remove(string $finisherIdentifier, string $key);
1274
1275
1276 .. _apireference-frontendrendering-programmatically-apimethods-configurationservice:
1277
1278 TYPO3\\CMS\\Form\\Domain\\Configuration\\ConfigurationService
1279 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1280
1281 .. _apireference-frontendrendering-programmatically-apimethods-configurationservice-getprototypeconfiguration:
1282
1283 getPrototypeConfiguration()
1284 '''''''''''''''''''''''''''
1285
1286 Get the configuration for a given $prototypeName
1287
1288 Signature::
1289
1290    public function getPrototypeConfiguration(string $prototypeName): array;
1291
1292
1293 .. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory:
1294
1295 TYPO3\\CMS\\Form\\Domain\\Factory\\AbstractFormFactory
1296 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
1297
1298 .. _apireference-frontendrendering-programmatically-apimethods-abstractformfactory-triggerformbuildingfinished:
1299
1300 triggerFormBuildingFinished()
1301 '''''''''''''''''''''''''''''
1302
1303 Helper to be called by every ``FormFactory`` which extends from ``AbstractFormFactory`` after
1304 everything has been built to call the "afterBuildingFinished" hook on all form elements.
1305
1306 Signature::
1307
1308    protected function triggerFormBuildingFinished(FormDefinition $form);
1309
1310
1311 .. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface:
1312
1313 TYPO3\\CMS\\Form\\Domain\\Factory\\FormFactoryInterface
1314 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1315
1316 .. _apireference-frontendrendering-programmatically-apimethods-formfactoryinterface-build:
1317
1318 build()
1319 '''''''
1320
1321 Build a form definition, depending on some configuration.
1322
1323 Signature::
1324
1325    public function build(array $configuration, string $prototypeName = null): FormDefinition;
1326
1327
1328 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface:
1329
1330 TYPO3\\CMS\\Form\\Domain\\Renderer\\RendererInterface
1331 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1332
1333 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setcontrollercontext:
1334
1335 setControllerContext()
1336 ''''''''''''''''''''''
1337
1338 Set the controller context which should be used::
1339
1340    public function setControllerContext(ControllerContext $controllerContext);
1341
1342
1343 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-render:
1344
1345 render()
1346 ''''''''
1347
1348 Renders the FormDefinition. This method is expected to call the ``beforeRendering`` hook on each form element::
1349
1350     public function render(): string;
1351
1352
1353 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-setformruntime:
1354
1355 setFormRuntime()
1356 ''''''''''''''''
1357
1358 Set the current ``FormRuntime``::
1359
1360    public function setFormRuntime(FormRuntime $formRuntime);
1361
1362
1363 .. _apireference-frontendrendering-programmatically-apimethods-rendererinterface-getformruntime:
1364
1365 getFormRuntime()
1366 ''''''''''''''''
1367
1368 Get the current ``FormRuntime``::
1369
1370    public function getFormRuntime(): FormRuntime;
1371
1372
1373 .. _apireference-frontendrendering-runtimemanipulation:
1374
1375 Runtime manipulation
1376 --------------------
1377
1378 .. _apireference-frontendrendering-runtimemanipulation-hooks:
1379
1380 Hooks
1381 ^^^^^
1382
1383
1384 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement:
1385
1386 initializeFormElement
1387 +++++++++++++++++++++
1388
1389 You can connect to the hook and initialize a form elements without defining a
1390 custom implementaion to access the element's ``initializeFormElement`` method.
1391 You only need a class which connects to this hook. Then detect the form
1392 element you wish to initialize. You can use this hook to prefill form element
1393 data for example from database tables. Note that this hook will be called
1394 **after** all properties from the prototype configuration are set in the form
1395 element but **before** the properties from the form definition are set in the
1396 form element. If you want to prefill form element data after the complete form
1397 element is configured you should use the
1398 :ref:`afterBuildingFinished<apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished>` hook.
1399
1400 The initializeFormElement hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::createElement()``
1401 and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::createElement()``.
1402 That means the hook will **not** be triggered for ``Pages``. At this point
1403 you do not have access to submitted form element values.
1404
1405
1406 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-connect:
1407
1408 Connect to the hook
1409 '''''''''''''''''''
1410
1411 ::
1412
1413    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
1414        = \VENDOR\YourNamespace\YourClass::class;
1415
1416
1417 .. note::
1418
1419    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1420    means?
1421
1422
1423 .. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-use:
1424
1425 Use the hook
1426 ''''''''''''
1427
1428 ::
1429
1430    /**
1431     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1432     * @return void
1433     */
1434    public function initializeFormElement(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1435    {
1436        if ($renderable->getUniqueIdentifier() === 'contactForm-text-1') {
1437            $renderable->setDefaultValue('foo');
1438        }
1439    }
1440
1441
1442 .. _useATimestampAsKeyPlease:
1443
1444 What does <useATimestampAsKeyPlease> mean?
1445 ++++++++++++++++++++++++++++++++++++++++++
1446
1447 Timestamps are recommended for hooks such as those of the form framework, as
1448 seen in the following example::
1449
1450    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][<useATimestampAsKeyPlease>]
1451        = \VENDOR\YourNamespace\YourClass::class;
1452
1453
1454 Leaving the section ``<useATimestampAsKeyPlease>`` as is is not recommended.
1455 It does nothing except cause the extension to fail and an error message to be
1456 delivered. Nor should it be replaced with a function like time(), as the key
1457 should be unalterable. Instead, replace this section with the current UNIX
1458 timestamp the moment you are implementing the hook. Check out the following
1459 example::
1460
1461    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement'][1507018413]
1462        = \VENDOR\YourNamespace\YourClass::class;
1463
1464
1465 The purpose of timestamps is to prevent conflicts that arise when two or more
1466 extensions within one TYPO3 installation use identical keys (e.g.
1467 ``$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['initializeFormElement']['foo'])``.
1468 When timestamps are used, even a one-second difference in the time different
1469 hooks were connected ensures that one hook does not override the other.
1470
1471
1472 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable:
1473
1474 beforeRemoveFromParentRenderable
1475 ++++++++++++++++++++++++++++++++
1476
1477 This hook is invoked by the methods ``TYPO3\CMS\Form\Domain\Model\FormDefinition::removePage()``,  ``TYPO3\CMS\Form\Domain\Model\FormElements\Page::removeElement()``
1478 and ``TYPO3\CMS\Form\Domain\Model\FormElements\Section::removeElement()``
1479
1480
1481 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-connect:
1482
1483 Connect to the hook
1484 '''''''''''''''''''
1485
1486 ::
1487
1488    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRemoveFromParentRenderable'][<useATimestampAsKeyPlease>]
1489        = \VENDOR\YourNamespace\YourClass::class;
1490
1491
1492 .. note::
1493
1494    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1495    means?
1496
1497
1498 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-use:
1499
1500 Use the hook
1501 ''''''''''''
1502
1503 ::
1504
1505    /**
1506     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1507     * @return void
1508     */
1509    public function beforeRemoveFromParentRenderable(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1510    {
1511    }
1512
1513
1514 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished:
1515
1516 afterBuildingFinished
1517 +++++++++++++++++++++
1518
1519 This hook is called for each form element after the class ``TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory``
1520 has built the entire form. This hook is triggered just before the
1521 ``FormRuntime`` object is generated. At this point, no run-time information
1522 (e.g. assigned form values) is yet available. It can, for example, be used to
1523 generate new form elements within complex forms. The ``ArrayFormFactory`` is
1524 used by EXT:form via the ``RenderViewHelper`` to render forms using a ``form
1525 definition`` YAML file. Each form factory implementation must deal with the
1526 calling of this hook themselves. EXT:form itself uses this hook to initialize
1527 the property-mapper configuration for ``FileUpload`` elements.
1528
1529 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-connect:
1530
1531 Connect to the hook
1532 '''''''''''''''''''
1533
1534 ::
1535
1536    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterBuildingFinished'][<useATimestampAsKeyPlease>]
1537        = \VENDOR\YourNamespace\YourClass::class;
1538
1539
1540 .. note::
1541
1542    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1543    means?
1544
1545
1546 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-use:
1547
1548 Use the hook
1549 ''''''''''''
1550
1551 ::
1552
1553    /**
1554     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1555     * @return void
1556     */
1557    public function afterBuildingFinished(\TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable)
1558    {
1559    }
1560
1561
1562 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage:
1563
1564 afterInitializeCurrentPage
1565 ++++++++++++++++++++++++++
1566
1567 EXT:form automatically detects the page that should be shown and allow users
1568 only to jump to the directly following (or previous) pages. This hook enables
1569 you to implement a custom behavior, for example pages that are shown only when
1570 other form elements have specific values.
1571
1572
1573 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-connect:
1574
1575 Connect to the hook
1576 '''''''''''''''''''
1577
1578 ::
1579
1580    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterInitializeCurrentPage'][<useATimestampAsKeyPlease>]
1581        = \VENDOR\YourNamespace\YourClass::class;
1582
1583
1584 .. note::
1585
1586    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1587    means?
1588
1589
1590 .. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-use:
1591
1592 Use the hook
1593 ''''''''''''
1594
1595 ::
1596
1597    /**
1598     * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1599     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $currentPage
1600     * @param null|\TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface $lastPage
1601     * @param mixed $elementValue submitted value of the element *before post processing*
1602     * @return \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
1603     */
1604    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 = []): \TYPO3\CMS\Form\Domain\Model\Renderable\CompositeRenderableInterface
1605    {
1606        return $currentPage;
1607    }
1608
1609
1610 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit:
1611
1612 afterSubmit
1613 +++++++++++
1614
1615 You can use it for example for dynamic validations which depends on other submitted form element values.
1616 This hook is invoked by the ``FormRuntime`` for each form element **before** values are property mapped, validated and pushed within the FormRuntime's ``FormState``.
1617 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
1618 the submitted form element values from the first page. In this case you can access the submitted raw data through ``$requestArguments``.
1619 EXT:form itself uses this hook to dynamically add validation errors for ``AdvancedPassword`` form elements.
1620
1621
1622 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-connect:
1623
1624 Connect to the hook
1625 '''''''''''''''''''
1626
1627 ::
1628
1629    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['afterSubmit'][<useATimestampAsKeyPlease>]
1630        = \VENDOR\YourNamespace\YourClass::class;
1631
1632
1633 .. note::
1634
1635    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1636    means?
1637
1638
1639 .. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-use:
1640
1641 Use the hook
1642 ''''''''''''
1643
1644 ::
1645
1646    /**
1647     * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1648     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable
1649     * @param mixed $elementValue submitted value of the element *before post processing*
1650     * @param array $requestArguments submitted raw request values
1651     * @return void
1652     */
1653    public function afterSubmit(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RenderableInterface $renderable, $elementValue, array $requestArguments = [])
1654    {
1655        return $elementValue;
1656    }
1657
1658
1659 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering:
1660
1661 beforeRendering
1662 +++++++++++++++
1663
1664 This is a hook that is invoked by the rendering system before the corresponding element is rendered.
1665 Use this to access previously submitted values and/or modify the ``FormRuntime`` before an element is outputted to the browser.
1666 This hook is called after all validations and property mappings are done.
1667
1668 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-connect:
1669
1670 Connect to the hook
1671 '''''''''''''''''''
1672
1673 ::
1674
1675    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeRendering'][<useATimestampAsKeyPlease>]
1676        = \VENDOR\YourNamespace\YourClass::class;
1677
1678
1679 .. note::
1680
1681    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
1682    means?
1683
1684
1685 .. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-use:
1686
1687 Use the hook
1688 ''''''''''''
1689
1690 ::
1691
1692    /**
1693     * @param \TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime
1694     * @param \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable
1695     * @return void
1696     */
1697    public function beforeRendering(\TYPO3\CMS\Form\Domain\Runtime\FormRuntime $formRuntime, \TYPO3\CMS\Form\Domain\Model\Renderable\RootRenderableInterface $renderable)
1698    {
1699    }
1700
1701
1702 .. _apireference-finisheroptions:
1703
1704 Finisher Options
1705 ================
1706
1707 .. _apireference-finisheroptions-closurefinisher:
1708
1709 Closure finisher
1710 ----------------
1711
1712 This finisher can only be used in programmatically-created forms. It makes it
1713 possible to execute one's own finisher code without having to implement/
1714 declare this finisher.
1715
1716 Usage through code::
1717
1718    $closureFinisher = $this->objectManager->get(ClosureFinisher::class);
1719    $closureFinisher->setOption('closure', function($finisherContext) {
1720        $formRuntime = $finisherContext->getFormRuntime();
1721        // ...
1722    });
1723    $formDefinition->addFinisher($closureFinisher);
1724
1725
1726 .. _apireference-finisheroptions-closurefinisher-options:
1727
1728 Options
1729 ^^^^^^^
1730
1731 .. _apireference-finisheroptions-closurefinisher-options-closure:
1732
1733 closure
1734 +++++++
1735
1736 :aspect:`Data type`
1737       \Closure
1738
1739 :aspect:`Mandatory`
1740       Yes
1741
1742 :aspect:`Default value`
1743       null
1744
1745
1746 .. _apireference-finisheroptions-confirmationfinisher:
1747
1748 Confirmation finisher
1749 ---------------------
1750
1751 A simple finisher that outputs a given text.
1752
1753 Usage within form definition
1754
1755 .. code-block:: yaml
1756
1757    identifier: example-form
1758    label: 'example'
1759    type: Form
1760
1761    finishers:
1762      -
1763        identifier: Confirmation
1764        options:
1765          message: 'Thx for using TYPO3'
1766    ...
1767
1768
1769 Usage through code::
1770
1771    $formDefinition->createFinisher('Confirmation', [
1772        'message' => 'foo',
1773    ]);
1774
1775 or create manually (not preferred)::
1776
1777    $confirmationFinisher = $this->objectManager->get(ConfirmationFinisher::class);
1778    $confirmationFinisher->setOptions([
1779        'message' => 'foo',
1780    ]);
1781    $formDefinition->addFinisher($confirmationFinisher);
1782
1783
1784 .. _apireference-finisheroptions-confirmationfinisher-options:
1785
1786 Options
1787 ^^^^^^^
1788
1789 .. _apireference-finisheroptions-confirmationfinisher-options-message:
1790
1791 message
1792 +++++++
1793
1794 :aspect:`Data type`
1795       string
1796
1797 :aspect:`Mandatory`
1798       Yes
1799
1800 :aspect:`Default value`
1801       The form has been submitted.
1802
1803
1804 .. _apireference-finisheroptions-deleteuploadsfinisher:
1805
1806 DeleteUploads finisher
1807 ----------------------
1808
1809 This finisher remove the currently submited files.
1810 Use this finisher e.g after the email finisher if you don't want to keep the files online.
1811
1812
1813 Usage within form definition
1814
1815 .. code-block:: yaml
1816
1817    identifier: example-form
1818    label: 'example'
1819    type: Form
1820
1821    finishers:
1822      -
1823        identifier: DeleteUploads
1824    ...
1825
1826
1827 Usage through code::
1828
1829    $formDefinition->createFinisher('DeleteUploads');
1830
1831 or create manually (not preferred)::
1832
1833    $deleteUploadsFinisher = $this->objectManager->get(DeleteUploadsFinisher::class);
1834    $formDefinition->addFinisher($deleteUploadsFinisher);
1835
1836
1837 .. _apireference-finisheroptions-emailfinisher:
1838
1839 Email finisher
1840 --------------
1841
1842 This finisher sends an email to one recipient.
1843 EXT:form uses 2 EmailFinisher declarations with the identifiers ``EmailToReceiver`` and ``EmailToSender``.
1844
1845 Usage within form definition
1846
1847 .. code-block:: yaml
1848
1849    identifier: example-form
1850    label: 'example'
1851    type: Form
1852
1853    finishers:
1854      -
1855        identifier: EmailToReceiver
1856        options:
1857          subject: 'Your message'
1858          recipientAddress: your.company@example.com
1859          recipientName: 'Your Company name'
1860          senderAddress: 'form@example.com'
1861          senderName: 'form submitter'
1862    ...
1863
1864
1865 Usage through code::
1866
1867    $formDefinition->createFinisher('EmailToReceiver', [
1868        'subject' => 'Your message',
1869        'recipientAddress' => 'your.company@example.com',
1870        'recipientName' => 'Your Company name',
1871        'senderAddress' => 'form@example.com',
1872        'senderName' => 'form submitter',
1873    ]);
1874
1875 or create manually (not preferred)::
1876
1877    $emailFinisher = $this->objectManager->get(EmailFinisher::class);
1878    $emailFinisher->setOptions([
1879        'subject' => 'Your message',
1880        'recipientAddress' => 'your.company@example.com',
1881        'recipientName' => 'Your Company name',
1882        'senderAddress' => 'form@example.com',
1883        'senderName' => 'form submitter',
1884    ]);
1885    $formDefinition->addFinisher($emailFinisher);
1886
1887
1888 .. _apireference-finisheroptions-emailfinisher-options:
1889
1890 Options
1891 ^^^^^^^
1892
1893 .. _apireference-finisheroptions-emailfinisher-options-subject:
1894
1895 subject
1896 +++++++
1897
1898 :aspect:`Data type`
1899       string
1900
1901 :aspect:`Mandatory`
1902       Yes
1903
1904 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1905       undefined
1906
1907 :aspect:`Description`
1908       Subject of the email
1909
1910
1911 .. _apireference-finisheroptions-emailfinisher-options-recipientaddress:
1912
1913 recipientAddress
1914 ++++++++++++++++
1915
1916 :aspect:`Data type`
1917       string
1918
1919 :aspect:`Mandatory`
1920       Yes
1921
1922 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1923       undefined
1924
1925 :aspect:`Description`
1926       Email address of the recipient (To)
1927
1928
1929 .. _apireference-finisheroptions-emailfinisher-options-recipientname:
1930
1931 recipientName
1932 +++++++++++++
1933
1934 :aspect:`Data type`
1935       string
1936
1937 :aspect:`Mandatory`
1938       No
1939
1940 :aspect:`Default value`
1941       empty string
1942
1943 :aspect:`Description`
1944       Human-readable name of the recipient
1945
1946
1947 .. _apireference-finisheroptions-emailfinisher-options-senderaddress:
1948
1949 senderAddress
1950 +++++++++++++
1951
1952 :aspect:`Data type`
1953       string
1954
1955 :aspect:`Mandatory`
1956       Yes
1957
1958 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1959       undefined
1960
1961 :aspect:`Description`
1962       Email address of the sender/ visitor (From)
1963
1964
1965 .. _apireference-finisheroptions-emailfinisher-options-sendername:
1966
1967 senderName
1968 ++++++++++
1969
1970 :aspect:`Data type`
1971       string
1972
1973 :aspect:`Mandatory`
1974       No
1975
1976 :aspect:`Default value`
1977       empty string
1978
1979 :aspect:`Description`
1980       Human-readable name of the sender
1981
1982
1983 .. _apireference-finisheroptions-emailfinisher-options-replytoaddress:
1984
1985 replyToAddress
1986 ++++++++++++++
1987
1988 :aspect:`Data type`
1989       string/ array
1990
1991 :aspect:`Mandatory`
1992       No
1993
1994 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
1995       undefined
1996
1997 :aspect:`Description`
1998       Email address of to be used as reply-to email (use multiple addresses with an array)
1999
2000 .. note::
2001
2002    For the moment, the ``form editor`` cannot deal with multiple reply-to addresses (use multiple addresses with an array)
2003
2004
2005 .. _apireference-finisheroptions-emailfinisher-options-carboncopyaddress:
2006
2007 carbonCopyAddress
2008 +++++++++++++++++
2009
2010 :aspect:`Data type`
2011       string/ array
2012
2013 :aspect:`Mandatory`
2014       No
2015
2016 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2017       undefined
2018
2019 :aspect:`Description`
2020       Email address of the copy recipient (use multiple addresses with an array)
2021
2022 .. note::
2023
2024    For the moment, the ``form editor`` cannot deal with multiple copy recipient addresses (use multiple addresses with an array)
2025
2026
2027 .. _apireference-finisheroptions-emailfinisher-options-blindcarboncopyaddress:
2028
2029 blindCarbonCopyAddress
2030 ++++++++++++++++++++++
2031
2032 :aspect:`Data type`
2033       string/ array
2034
2035 :aspect:`Mandatory`
2036       No
2037
2038 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2039       undefined
2040
2041 :aspect:`Description`
2042       Email address of the blind copy recipient (use multiple addresses with an array)
2043
2044 .. note::
2045
2046    For the moment, the ``form editor`` cannot deal with multiple blind copy recipient addresses (use multiple addresses with an array)
2047
2048
2049 .. _apireference-finisheroptions-emailfinisher-options-format:
2050
2051 format
2052 ++++++
2053
2054 :aspect:`Data type`
2055       string
2056
2057 :aspect:`Mandatory`
2058       No
2059
2060 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2061       html
2062
2063 :aspect:`possible values`
2064       html/ plaintext
2065
2066 :aspect:`Description`
2067       The format of the email. By default mails are sent as HTML.
2068
2069
2070 .. _apireference-finisheroptions-emailfinisher-options-attachuploads:
2071
2072 attachUploads
2073 +++++++++++++
2074
2075 :aspect:`Data type`
2076       bool
2077
2078 :aspect:`Mandatory`
2079       No
2080
2081 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2082       true
2083
2084 :aspect:`Description`
2085       If set, all uploaded items are attached to the email.
2086
2087
2088 .. _apireference-finisheroptions-emailfinisher-options-translation-translationfile:
2089
2090 translation.translationFile
2091 +++++++++++++++++++++++++++
2092
2093 :aspect:`Data type`
2094       string/ array
2095
2096 :aspect:`Mandatory`
2097       No
2098
2099 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2100       undefined
2101
2102 :aspect:`Description`
2103       If set, this translation file(s) will be used for finisher option translations.
2104       If not set, the translation file(s) from the 'Form' element will be used.
2105       Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
2106
2107
2108 .. _apireference-finisheroptions-emailfinisher-options-translation-language:
2109
2110 translation.language
2111 ++++++++++++++++++++
2112
2113 :aspect:`Data type`
2114       string
2115
2116 :aspect:`Mandatory`
2117       No
2118
2119 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2120       undefined
2121
2122 :aspect:`Description`
2123       If not set, the finisher options are translated depending on the current frontend language (if translations exists).
2124       This option allows you to force translations for a given sys_language isocode, e.g 'dk' or 'de'.
2125       Read :ref:`Translate finisher options<concepts-frontendrendering-translation-finishers>` for more informations.
2126
2127
2128 .. _apireference-finisheroptions-emailfinisher-options-templatepathandfilename:
2129
2130 templatePathAndFilename
2131 +++++++++++++++++++++++
2132
2133 :aspect:`Data type`
2134       string
2135
2136 :aspect:`Mandatory`
2137       Yes
2138
2139 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2140       'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/{@format}.html'
2141
2142 :aspect:`Description`
2143       Template path and filename for the mail body.
2144       The placeholder {\@format} will be replaced with the value from option ``format``
2145
2146
2147 .. _apireference-finisheroptions-emailfinisher-options-layoutrootpaths:
2148
2149 layoutRootPaths
2150 +++++++++++++++
2151
2152 :aspect:`Data type`
2153       array
2154
2155 :aspect:`Mandatory`
2156       No
2157
2158 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2159       undefined
2160
2161 :aspect:`Description`
2162       Fluid layout paths
2163
2164
2165 .. _apireference-finisheroptions-emailfinisher-options-partialrootpaths:
2166
2167 partialRootPaths
2168 ++++++++++++++++
2169
2170 :aspect:`Data type`
2171       array
2172
2173 :aspect:`Mandatory`
2174       No
2175
2176 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2177       undefined
2178
2179 :aspect:`Description`
2180       Fluid partial paths
2181
2182
2183 .. _apireference-finisheroptions-emailfinisher-options-variables:
2184
2185 variables
2186 +++++++++
2187
2188 :aspect:`Data type`
2189       array
2190
2191 :aspect:`Mandatory`
2192       No
2193
2194 :aspect:`Default value (for 'EmailToReceiver' and 'EmailToSender' declarations)`
2195       undefined
2196
2197 :aspect:`Description`
2198       associative array of variables which are available inside the Fluid template
2199
2200
2201 .. _apireference-finisheroptions-flashmessagefinisher:
2202
2203 FlashMessage finisher
2204 ---------------------
2205
2206 A simple finisher that adds a message to the FlashMessageContainer.
2207
2208 Usage within form definition
2209
2210 .. code-block:: yaml
2211
2212    identifier: example-form
2213    label: 'example'
2214    type: Form
2215
2216    finishers:
2217      -
2218        identifier: FlashMessage
2219        options:
2220          messageBody: 'Thx for using TYPO3'
2221          messageTitle: 'Merci'
2222          severity: 0
2223    ...
2224
2225
2226 Usage through code::
2227
2228    $formDefinition->createFinisher('FlashMessage', [
2229        'messageBody' => 'Thx for using TYPO3',
2230        'messageTitle' => 'Merci',
2231        'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
2232    ]);
2233
2234 or create manually (not preferred)::
2235
2236    $flashMessageFinisher = $this->objectManager->get(FlashMessageFinisher::class);
2237    $flashMessageFinisher->setOptions([
2238        'messageBody' => 'Thx for using TYPO3',
2239        'messageTitle' => 'Merci',
2240        'severity' => \TYPO3\CMS\Core\Messaging\AbstractMessage::OK,
2241    ]);
2242    $formDefinition->addFinisher($flashMessageFinisher);
2243
2244
2245 .. _apireference-finisheroptions-flashmessagefinisher-options:
2246
2247 Options
2248 ^^^^^^^
2249
2250 .. _apireference-finisheroptions-flashmessagefinisher-options-messagebody:
2251
2252 messageBody
2253 +++++++++++
2254
2255 :aspect:`Data type`
2256       string
2257
2258 :aspect:`Mandatory`
2259       Yes
2260
2261 :aspect:`Default value`
2262       null
2263
2264 :aspect:`Description`
2265       The flash message body
2266
2267
2268 .. _apireference-finisheroptions-flashmessagefinisher-options-messagetitle:
2269
2270 messageTitle
2271 ++++++++++++
2272
2273 :aspect:`Data type`
2274       string
2275
2276 :aspect:`Mandatory`
2277       No
2278
2279 :aspect:`Default value`
2280       empty string
2281
2282 :aspect:`Description`
2283       The flash message title
2284
2285
2286 .. _apireference-finisheroptions-flashmessagefinisher-options-messagearguments:
2287
2288 messageArguments
2289 ++++++++++++++++
2290
2291 :aspect:`Data type`
2292       array
2293
2294 :aspect:`Mandatory`
2295       No
2296
2297 :aspect:`Default value`
2298       empty array
2299
2300 :aspect:`Description`
2301       The flash message arguments, if needed
2302
2303
2304 .. _apireference-finisheroptions-flashmessagefinisher-options-messagecode:
2305
2306 messageCode
2307 +++++++++++
2308
2309 :aspect:`Data type`
2310       int
2311
2312 :aspect:`Mandatory`
2313       No
2314
2315 :aspect:`Default value`
2316       null
2317
2318 :aspect:`Description`
2319       The flash message code, if needed
2320
2321
2322 .. _apireference-finisheroptions-flashmessagefinisher-options-severity:
2323
2324 severity
2325 ++++++++
2326
2327 :aspect:`Data type`
2328       int
2329
2330 :aspect:`Mandatory`
2331       No
2332
2333 :aspect:`Default value`
2334       \TYPO3\CMS\Core\Messaging\AbstractMessage::OK (0)
2335
2336 :aspect:`Description`
2337       The flash message severity code.
2338       See \TYPO3\CMS\Core\Messaging\AbstractMessage constants for the codes.
2339
2340
2341 .. _apireference-finisheroptions-redirectfinisher:
2342
2343 Redirect finisher
2344 -----------------
2345
2346 A simple finisher that redirects to another page.
2347
2348 Usage within form definition
2349
2350 .. code-block:: yaml
2351
2352    identifier: example-form
2353    label: 'example'
2354    type: Form
2355
2356    finishers:
2357      -
2358        identifier: Redirect
2359        options:
2360          pageUid: 1
2361          additionalParameters: 'param1=value1&param2=value2'
2362    ...
2363
2364
2365 Usage through code::
2366
2367    $formDefinition->createFinisher('Redirect', [
2368        'pageUid' => 1,
2369        'additionalParameters' => 'param1=value1&param2=value2',
2370    ]);
2371
2372 or create manually (not preferred)::
2373
2374    $redirectFinisher = $this->objectManager->get(RedirectFinisher::class);
2375    $redirectFinisher->setOptions([
2376        'pageUid' => 1,
2377        'additionalParameters' => 'param1=value1&param2=value2',
2378    ]);
2379    $formDefinition->addFinisher($redirectFinisher);
2380
2381
2382 .. _apireference-finisheroptions-redirectfinisher-options:
2383
2384 Options
2385 ^^^^^^^
2386
2387 .. _apireference-finisheroptions-redirectfinisher-options-pageuid:
2388
2389 pageUid
2390 +++++++
2391
2392 :aspect:`Data type`
2393       int
2394
2395 :aspect:`Mandatory`
2396       Yes
2397
2398 :aspect:`Default value`
2399       1
2400
2401 :aspect:`Description`
2402       Redirect to this page uid
2403
2404
2405 .. _apireference-finisheroptions-redirectfinisher-options-additionalparameters:
2406
2407 additionalParameters
2408 ++++++++++++++++++++
2409
2410 :aspect:`Data type`
2411       string
2412
2413 :aspect:`Mandatory`
2414       No
2415
2416 :aspect:`Default value`
2417       empty string
2418
2419 :aspect:`Description`
2420       Additional parameters which should be used on the target page
2421
2422
2423 .. _apireference-finisheroptions-redirectfinisher-options-delay:
2424
2425 delay
2426 +++++
2427
2428 :aspect:`Data type`
2429       int
2430
2431 :aspect:`Mandatory`
2432       No
2433
2434 :aspect:`Default value`
2435       0
2436
2437 :aspect:`Description`
2438       The redirect delay in seconds.
2439
2440
2441 .. _apireference-finisheroptions-redirectfinisher-options-statuscode:
2442
2443 statusCode
2444 ++++++++++
2445
2446 :aspect:`Data type`
2447       int
2448
2449 :aspect:`Mandatory`
2450       No
2451
2452 :aspect:`Default value`
2453       303
2454
2455 :aspect:`Description`
2456       The HTTP status code for the redirect. Default is "303 See Other".
2457
2458
2459 .. _apireference-finisheroptions-savetodatabasefinisher:
2460
2461 SaveToDatabase finisher
2462 -----------------------
2463
2464 This finisher saves the data from a submitted form into a database table.
2465
2466
2467 Usage within form definition
2468
2469 .. code-block:: yaml
2470
2471    identifier: example-form
2472    label: 'example'
2473    type: Form
2474
2475    finishers:
2476      -
2477        identifier: SaveToDatabase
2478        options:
2479          table: 'fe_users'
2480          mode: update
2481          whereClause:
2482            uid: 1
2483          databaseColumnMappings:
2484            pid:
2485              value: 1
2486          elements:
2487            textfield-identifier-1:
2488              mapOnDatabaseColumn: 'first_name'
2489            textfield-identifier-2:
2490              mapOnDatabaseColumn: 'last_name'
2491            textfield-identifier-3:
2492              mapOnDatabaseColumn: 'username'
2493            advancedpassword-1:
2494              mapOnDatabaseColumn: 'password'
2495              skipIfValueIsEmpty: true
2496    ...
2497
2498
2499 Usage through code::
2500
2501    $formDefinition->createFinisher('SaveToDatabase', [
2502        'table' => 'fe_users',
2503        'mode' => 'update',
2504        'whereClause' => [
2505            'uid' => 1,
2506        ],
2507        'databaseColumnMappings' => [
2508            'pid' => ['value' => 1],
2509        ],
2510        'elements' => [
2511            'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
2512            'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
2513            'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
2514            'advancedpassword-1' => [
2515                'mapOnDatabaseColumn' => 'password',
2516                'skipIfValueIsEmpty' => true,
2517            ],
2518        ],
2519    ]);
2520
2521 or create manually (not preferred)::
2522
2523    $saveToDatabaseFinisher = $this->objectManager->get(SaveToDatabaseFinisher::class);
2524    $saveToDatabaseFinisher->setOptions([
2525        'table' => 'fe_users',
2526        'mode' => 'update',
2527        'whereClause' => [
2528            'uid' => 1,
2529        ],
2530        'databaseColumnMappings' => [
2531            'pid' => ['value' => 1],
2532        ],
2533        'elements' => [
2534            'textfield-identifier-1' => ['mapOnDatabaseColumn' => 'first_name'],
2535            'textfield-identifier-2' => ['mapOnDatabaseColumn' => 'last_name'],
2536            'textfield-identifier-3' => ['mapOnDatabaseColumn' => 'username'],
2537            'advancedpassword-1' => [
2538                'mapOnDatabaseColumn' => 'password',
2539                'skipIfValueIsEmpty' => true,
2540            ],
2541        ],
2542    ]);
2543    $formDefinition->addFinisher($saveToDatabaseFinisher);
2544
2545 You can write options as an array to perform multiple database operations.
2546
2547 Usage within form definition
2548
2549 .. code-block:: yaml
2550
2551    identifier: example-form
2552    label: 'example'
2553    type: Form
2554
2555    finishers:
2556      -
2557        identifier: SaveToDatabase
2558        options:
2559          1:
2560            table: 'my_table'
2561            mode: insert
2562            databaseColumnMappings:
2563              some_column:
2564                value: 'cool'
2565          2:
2566            table: 'my_other_table'
2567            mode: update
2568            whereClause:
2569              pid: 1
2570            databaseColumnMappings:
2571              some_other_column:
2572                value: '{SaveToDatabase.insertedUids.1}'
2573    ...
2574
2575
2576 Usage through code::
2577
2578    $formDefinition->createFinisher('SaveToDatabase', [
2579        1 => [
2580            'table' => 'my_table',
2581            'mode' => 'insert',
2582            'databaseColumnMappings' => [
2583                'some_column' => ['value' => 'cool'],
2584            ],
2585        ],
2586        2 => [
2587            'table' => 'my_other_table',
2588            'mode' => 'update',
2589            'whereClause' => [
2590                'pid' => 1,
2591            ],
2592            'databaseColumnMappings' => [
2593                'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
2594            ],
2595        ],
2596    ]);
2597
2598 or create manually (not preferred)::
2599
2600    $saveToDatabaseFinisher = $this->objectManager->get(SaveToDatabaseFinisher::class);
2601    $saveToDatabaseFinisher->setOptions([
2602        1 => [
2603            'table' => 'my_table',
2604            'mode' => 'insert',
2605            'databaseColumnMappings' => [
2606                'some_column' => ['value' => 'cool'],
2607            ],
2608        ],
2609        2 => [
2610            'table' => 'my_other_table',
2611            'mode' => 'update',
2612            'whereClause' => [
2613                'pid' => 1,
2614            ],
2615            'databaseColumnMappings' => [
2616                'some_other_column' => ['value' => '{SaveToDatabase.insertedUids.1}'],
2617            ],
2618        ],
2619    ]);
2620    $formDefinition->addFinisher($saveToDatabaseFinisher);
2621
2622
2623 This performs 2 database operations.
2624 One insert and one update.
2625 You can access the inserted uids through '{SaveToDatabase.insertedUids.<theArrayKeyNumberWithinOptions>}'
2626 If you perform a insert operation, the value of the inserted database row will be stored within the FinisherVariableProvider.
2627 <theArrayKeyNumberWithinOptions> references to the numeric options.* key.
2628
2629
2630 .. _apireference-finisheroptions-savetodatabasefinisher-options:
2631
2632 Options
2633 ^^^^^^^
2634
2635 .. _apireference-finisheroptions-savetodatabasefinisher-options-table:
2636
2637 table
2638 +++++
2639
2640 :aspect:`Data type`
2641       string
2642
2643 :aspect:`Mandatory`
2644       Yes
2645
2646 :aspect:`Default value`
2647       null
2648
2649 :aspect:`Description`
2650       Insert or update values into this table.
2651
2652
2653 .. _apireference-finisheroptions-savetodatabasefinisher-options-mode:
2654
2655 mode
2656 ++++
2657
2658 :aspect:`Data type`
2659       string
2660
2661 :aspect:`Mandatory`
2662       No
2663
2664 :aspect:`Default value`
2665       'insert'
2666
2667 :aspect:`Possible values`
2668       insert/ update
2669
2670 :aspect:`Description`
2671       ``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
2672
2673       ``update`` will update a given database row with the values from the submitted form and/or some predefined values. 'options.whereClause' is then required.
2674
2675
2676 .. _apireference-finisheroptions-savetodatabasefinisher-options-whereclause:
2677
2678 whereClause
2679 +++++++++++
2680
2681 :aspect:`Data type`
2682       array
2683
2684 :aspect:`Mandatory`
2685       Yes, if mode = update
2686
2687 :aspect:`Default value`
2688       empty array
2689
2690 :aspect:`Description`
2691       This where clause will be used for a database update action
2692
2693
2694 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements:
2695
2696 elements
2697 ++++++++
2698
2699 :aspect:`Data type`
2700       array
2701
2702 :aspect:`Mandatory`
2703       Yes
2704
2705 :aspect:`Default value`
2706       empty array
2707
2708 :aspect:`Description`
2709       Use ``options.elements`` to map form element values to existing database columns.
2710       Each key within ``options.elements`` has to match with a form element identifier.
2711       The value for each key within ``options.elements`` is an array with additional informations.
2712
2713
2714 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-mapondatabasecolumn:
2715
2716 elements.<formElementIdentifier>.mapOnDatabaseColumn
2717 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2718
2719 :aspect:`Data type`
2720       string
2721
2722 :aspect:`Mandatory`
2723       Yes
2724
2725 :aspect:`Default value`
2726       undefined
2727
2728 :aspect:`Description`
2729       The value from the submitted form element with the identifier ``<formElementIdentifier>`` will be written into this database column.
2730
2731
2732 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-skipifvalueisempty:
2733
2734 elements.<formElementIdentifier>.skipIfValueIsEmpty
2735 +++++++++++++++++++++++++++++++++++++++++++++++++++
2736
2737 :aspect:`Data type`
2738       bool
2739
2740 :aspect:`Mandatory`
2741       No
2742
2743 :aspect:`Default value`
2744       false
2745
2746 :aspect:`Description`
2747       Set this to true if the database column should not be written if the value from the submitted form element with the identifier
2748       ``<formElementIdentifier>`` is empty (think about password fields etc.). Empty means strings without content, whitespace is valid content.
2749
2750
2751 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-savefileidentifierinsteadofuid:
2752
2753 elements.<formElementIdentifier>.saveFileIdentifierInsteadOfUid
2754 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2755
2756 :aspect:`Data type`
2757       bool
2758
2759 :aspect:`Mandatory`
2760       No
2761
2762 :aspect:`Default value`
2763       false
2764
2765 :aspect:`Description`
2766       Set this to true if the database column should not be written if the value from the submitted form element with the identifier
2767       ``<formElementIdentifier>`` is empty (think about password fields etc.).
2768
2769       This setting only rules for form elements which creates a FAL object like ``FileUpload`` or ``ImageUpload``.
2770       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
2771       FAL identifier (1:/user_uploads/some_uploaded_pic.jpg) instead.
2772
2773
2774 .. _apireference-finisheroptions-savetodatabasefinisher-options-elements-<formelementidentifier>-dateformat:
2775
2776 elements.<formElementIdentifier>.dateFormat
2777 +++++++++++++++++++++++++++++++++++++++++++
2778
2779 :aspect:`Data type`
2780       string
2781
2782 :aspect:`Mandatory`
2783       No
2784
2785 :aspect:`Default value`
2786       'U'
2787
2788 :aspect:`Description`
2789       If the internal datatype is :php:`\DateTime` which is true for the form element types
2790       :yaml:`DatePicker` and :yaml:`Date`, the object needs to be converted into a string value.
2791       This option allows you to define the format of the date in case of such a conversion.
2792       You can use every format accepted by the PHP :php:`date()` function (http://php.net/manual/en/function.date.php#refsect1-function.date-parameters).
2793       The default value is "U" which leads to a Unix timestamp.
2794
2795
2796 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings:
2797
2798 databaseColumnMappings
2799 ++++++++++++++++++++++
2800
2801 :aspect:`Data type`
2802       array
2803
2804 :aspect:`Mandatory`
2805       No
2806
2807 :aspect:`Default value`
2808       empty array
2809
2810 :aspect:`Description`
2811       Use this to map database columns to static values.
2812       Each key within ``options.databaseColumnMappings`` has to match with an existing database column.
2813       The value for each key within ``options.databaseColumnMappings`` is an array with additional informations.
2814
2815       This mapping is done *before* the ``options.element`` mapping.
2816       This means if you map a database column to a value through ``options.databaseColumnMappings`` and map a submitted
2817       form element value to the same database column through ``options.element``, the submitted form element value
2818       will override the value you set within ``options.databaseColumnMappings``.
2819
2820
2821 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.value:
2822
2823 databaseColumnMappings.<databaseColumnName>.value
2824 +++++++++++++++++++++++++++++++++++++++++++++++++
2825
2826 :aspect:`Data type`
2827       string
2828
2829 :aspect:`Mandatory`
2830       Yes
2831
2832 :aspect:`Default value`
2833       undefined
2834
2835 :aspect:`Description`
2836       The value which will be written to the database column.
2837       You can also use the :ref:`FormRuntime accessor feature<concepts-frontendrendering-codecomponents-customfinisherimplementations-accessingoptions-formruntimeaccessor>` to access every getable property from the ``FormRuntime``
2838       In short: use something like ``{<formElementIdentifier>}`` to get the value from the submitted form element with the identifier ``<formElementIdentifier>``.
2839
2840       If you use the FormRuntime accessor feature within ``options.databaseColumnMappings``, the functionality is nearly identical
2841       to the ``options.elements`` configuration variant.
2842
2843
2844 .. _apireference-finisheroptions-savetodatabasefinisher-options-databasecolumnmappings.<databasecolumnname>.skipifvalueisempty:
2845
2846 databaseColumnMappings.<databaseColumnName>.skipIfValueIsEmpty
2847 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2848
2849 :aspect:`Data type`
2850       bool
2851
2852 :aspect:`Mandatory`
2853       No
2854
2855 :aspect:`Default value`
2856       false
2857
2858 :aspect:`Description`
2859       Set this to true if the database column should not be written if the value from ``options.databaseColumnMappings.<databaseColumnName>.value`` is empty. Empty means strings without content, whitespace is valid content.
2860
2861
2862 .. _apireference-formeditor:
2863
2864 Form editor
2865 ===========
2866
2867
2868 .. _apireference-formeditor-hooks:
2869
2870 Hooks
2871 -----
2872
2873 EXT:form implements various hooks so that forms can be manipulated while being
2874 created or saved.
2875
2876
2877 .. _apireference-formeditor-hooks-beforeformcreate:
2878
2879 beforeFormCreate
2880 ^^^^^^^^^^^^^^^^
2881
2882 The form manager calls the 'beforeFormCreate' hook.
2883
2884
2885 .. _apireference-formeditor-hooks-beforeformcreate-connect:
2886
2887 Connect to the hook
2888 +++++++++++++++++++
2889
2890 ::
2891
2892    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormCreate'][<useATimestampAsKeyPlease>]
2893        = \VENDOR\YourNamespace\YourClass::class;
2894
2895
2896 .. note::
2897
2898    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
2899    means?
2900
2901
2902 .. _apireference-formeditor-hooks-beforeformcreate-use:
2903
2904 Use the hook
2905 ++++++++++++
2906
2907 ::
2908
2909    /**
2910     * @param string $formPersistenceIdentifier
2911     * @param array $formDefinition
2912     * @return array
2913     */
2914    public function beforeFormCreate(string $formPersistenceIdentifier, array $formDefinition): array
2915    {
2916        return $formDefinition;
2917    }
2918
2919
2920 .. _apireference-formeditor-hooks-beforeformduplicate:
2921
2922 beforeFormDuplicate
2923 ^^^^^^^^^^^^^^^^^^^
2924
2925 The form manager call the 'beforeFormDuplicate' hook.
2926
2927
2928 .. _apireference-formeditor-hooks-beforeformduplicate-connect:
2929
2930 Connect to the hook
2931 +++++++++++++++++++
2932
2933 ::
2934
2935    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDuplicate'][<useATimestampAsKeyPlease>]
2936        = \VENDOR\YourNamespace\YourClass::class;
2937
2938
2939 .. note::
2940
2941    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
2942    means?
2943
2944
2945 .. _apireference-formeditor-hooks-beforeformduplicate-use:
2946
2947 Use the hook
2948 ++++++++++++
2949
2950 ::
2951
2952    /**
2953     * @param string $formPersistenceIdentifier
2954     * @param array $formDefinition
2955     * @return array
2956     */
2957    public function beforeFormDuplicate(string $formPersistenceIdentifier, array $formDefinition): array
2958    {
2959        return $formDefinition;
2960    }
2961
2962
2963 .. _apireference-formeditor-hooks-beforeformdelete:
2964
2965 beforeFormDelete
2966 ^^^^^^^^^^^^^^^^
2967
2968 The form manager call the 'beforeFormDelete' hook.
2969
2970
2971 .. _apireference-formeditor-hooks-beforeformdelete-connect:
2972
2973 Connect to the hook
2974 +++++++++++++++++++
2975
2976 ::
2977
2978    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormDelete'][<useATimestampAsKeyPlease>]
2979        = \VENDOR\YourNamespace\YourClass::class;
2980
2981
2982 .. note::
2983
2984    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
2985    means?
2986
2987
2988 .. _apireference-formeditor-hooks-beforeformdelete-use:
2989
2990 Use the hook
2991 ++++++++++++
2992
2993 ::
2994
2995    /**
2996     * @param string $formPersistenceIdentifier
2997     * @return void
2998     */
2999    public function beforeFormDelete(string $formPersistenceIdentifier)
3000    {
3001    }
3002
3003
3004 .. _apireference-formeditor-hooks-beforeformsave:
3005
3006 beforeFormSave
3007 ^^^^^^^^^^^^^^
3008
3009 The form editor call the 'beforeFormSave' hook.
3010
3011
3012 .. _apireference-formeditor-hooks-beforeformsave-connect:
3013
3014 Connect to the hook
3015 +++++++++++++++++++
3016
3017 ::
3018
3019    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/form']['beforeFormSave'][<useATimestampAsKeyPlease>]
3020        = \VENDOR\YourNamespace\YourClass::class;
3021
3022
3023 .. note::
3024
3025    Wondering what :ref:`useATimestampAsKeyPlease<useATimestampAsKeyPlease>`
3026    means?
3027
3028
3029 .. _apireference-formeditor-hooks-beforeformsave-use:
3030
3031 Use the hook
3032 ++++++++++++
3033
3034 ::
3035
3036    /**
3037     * @param string $formPersistenceIdentifier
3038     * @param array $formDefinition
3039     * @return array
3040     */
3041    public function beforeFormSave(string $formPersistenceIdentifier, array $formDefinition): array
3042    {
3043        return $formDefinition;
3044    }
3045
3046
3047 .. _apireference-formeditor-stage:
3048
3049 Stage
3050 -----
3051
3052
3053 .. _apireference-formeditor-stage-commonabstractformelementtemplates:
3054
3055 Common abstract view form element templates
3056 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3057
3058 The basic idea of the ``abstract view`` is to give a quick overview of the
3059 configuration of form elements, without having to click them in order to view
3060 the detailed configuration in the ``Inspector``. The ``form editor`` requires
3061 for each form element an inline HTML template and the corresponding JavaScript
3062 code. Information matching inline HTML templates to the appropriate form
3063 elements must be configured within :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
3064 At this point, the key identifying the form element follows a convention:
3065 ``FormElement-<formElementTypeIdentifier>``. The value for the key tells the
3066 ``form editor`` which inline HTML template should be loaded for the respective
3067 form element. This template is then cloned via JavaScript, brought to life
3068 using the form element configuration and shown in the ``Stage`` component.
3069
3070 You can read about how particular form elements are mapped to inline HTML
3071 templates and how the corresponding JavaScript code are executed :ref:`here <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`.
3072
3073 The form element inline HTML templates and the corresponding JavaScript code
3074 are configured for reuse. In this way, most form elements you create should be
3075 able to access the components delivered in EXT:form, without requiring separate
3076 implementations (at least we hope so). For your own implementations, study
3077 EXT:form stage templates, which is found under ``Resources/Private/Backend/Partials/FormEditor/Stage/*``.
3078 The corresponding JavaScript code is found under ``Resources/Public/JavaScript/Backend/FormEditor/StageComponent.js``.
3079 The method ``_renderTemplateDispatcher()`` shows, which methods will be used to
3080 render the respective form elements.
3081
3082 Essentially, two different inline HTML templates exists that can be rendered
3083 with two different JavaScript methods, which are described below. The other
3084 inline HTML templates are almost all versions of these two basic variants and
3085 show extra/ other form-element information. The same applies to the
3086 corresponding JavaScript codes.
3087
3088
3089 .. _apireference-formeditor-stage-commonabstractformelementtemplates-simpletemplate:
3090
3091 Stage/SimpleTemplate
3092 ++++++++++++++++++++
3093
3094 This template displays the ``label`` property of the form element. Depending on
3095 the JavaScript rendering method used, a validator icon will be shown on the
3096 right as soon as a validator is added to the form element. In this case, the
3097 used validator labels are likewise displayed, if the form element is selected
3098 and/ or the cursor hovers over the form element. This template should generally
3099 be enough for all possible, self-defined form elements.
3100
3101 The ``Stage/SimpleTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
3102 with the method ``getFormEditorApp().getViewModel().getStage().renderSimpleTemplateWithValidators()``.
3103
3104
3105 .. _apireference-formeditor-stage-commonabstractformelementtemplates-selecttemplate:
3106
3107 Stage/SelectTemplate
3108 ++++++++++++++++++++
3109
3110 This template behaves like the ``Stage/SimpleTemplate`` except that it also
3111 shows the chosen options labels of the form elements. This is naturally only
3112 possible for form elements that have ``properties.options.*`` values, e.g.
3113 ``MultiCheckbox``:
3114
3115 .. code-block:: yaml
3116
3117        type: MultiCheckbox
3118        identifier: multicheckbox-1
3119        label: 'Multi checkbox'
3120        properties:
3121          options:
3122            value1: label1
3123            value2: label2
3124
3125
3126 The template will now list 'label1' and 'label2'.
3127
3128 You can copy this template variant for your own form element, if that form-
3129 element template also lists array values, which, however, are not found under
3130 ``properties.options.*``. For this purpose, the 'Stage/FileUploadTemplate' is
3131 an example. It is basically the 'Stage/SelectTemplate' template, with one
3132 altered property.
3133
3134 In the ``FileUpload`` form element, multiple property values are available
3135 under ``properties.allowedMimeTypes.*`` as an array.
3136
3137 .. code-block:: yaml
3138
3139        type: FileUpload
3140        identifier: fileupload-1
3141        label: 'File upload'
3142        properties:
3143          saveToFileMount: '1:/user_upload/'
3144          allowedMimeTypes:
3145            - application/msexcel
3146            - application/pdf
3147
3148
3149 Stage/SelectTemplate
3150
3151 .. code-block:: html
3152
3153    <div data-identifier="multiValueContainer" data-template-property="properties.options">
3154
3155
3156 Stage/FileUploadTemplate
3157
3158 .. code-block:: html
3159
3160    <div data-identifier="multiValueContainer" data-template-property="properties.allowedMimeTypes">
3161
3162
3163 ``data-template-property`` contains the path to the property, which is to be
3164 read out of the form element and then shown in the template.
3165
3166 The ``Stage/SelectTemplate`` can then :ref:`be rendered <apireference-formeditor-basicjavascriptconcepts-events-view-stage-abstract-render-template-perform>`
3167 with the method ``getFormEditorApp().getViewModel().getStage().renderSelectTemplates()``.
3168
3169
3170 .. _apireference-formeditor-basicjavascriptconcepts:
3171
3172 Basic JavaScript Concepts
3173 -------------------------
3174
3175
3176 .. _apireference-formeditor-basicjavascriptconcepts-events:
3177
3178 Events
3179 ^^^^^^
3180
3181 EXT:form implements the ``publish/subscribe pattern`` to put the event handling
3182 into effect. To learn more about this pattern, you should read
3183 https://addyosmani.com/resources/essentialjsdesignpatterns/book/.
3184 Note that the order of the subscriber is not manipulable and that information
3185 flow between the subscribers does not exist. All events must be asynchronously
3186 designed.
3187
3188 Publish an event:
3189
3190 .. code-block:: javascript
3191
3192    getPublisherSubscriber().publish('eventname', [argumentToPublish1, argumentToPublish2, ...]);
3193
3194
3195 Subscribe to an event:
3196
3197 .. code-block:: javascript
3198
3199    var subscriberToken = getPublisherSubscriber().subscribe('eventname', function(topic, args) {
3200        // args[0] = argumentToPublish1
3201        // args[1] = argumentToPublish2
3202        // ...
3203    });
3204
3205
3206 Unsubscribe an event subscriber:
3207
3208 .. code-block:: javascript
3209
3210    getPublisherSubscriber().unsubscribe(subscriberToken);
3211
3212 EXT:form itself publishes and subscribes to the following events:
3213
3214 .. _apireference-formeditor-basicjavascriptconcepts-events-ajax-beforesend:
3215
3216 ajax/beforeSend
3217 +++++++++++++++
3218
3219 Each Ajax request is called before this event is sent. EXT:form uses this event
3220 to display the spinner icon on the save button.
3221
3222
3223 Subscribe to the event:
3224
3225 .. code-block:: javascript
3226
3227    /**
3228     * @private
3229     *
3230     * @param string
3231     * @param array
3232     * @return void
3233     */
3234    getPublisherSubscriber().subscribe('ajax/beforeSend', function(topic, args) {
3235    });
3236
3237
3238 .. _apireference-formeditor-basicjavascriptconcepts-events-ajax-complete:
3239
3240 ajax/complete
3241 +++++++++++++
3242
3243 Each Ajax request is called after the end of this event. EXT:form uses this
3244 event to remove the spinner icon on the save button.
3245
3246 Subscribe to the event:
3247
3248 .. code-block:: javascript
3249
3250    /**
3251     * @private
3252     *
3253     * @param string
3254     * @param array
3255     * @return void
3256     */
3257    getPublisherSubscriber().subscribe('ajax/complete', function(topic, args) {
3258    });
3259
3260
3261 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-error:
3262
3263 core/ajax/error
3264 +++++++++++++++
3265
3266 This event is called if the Ajax request, which is used to save the form or to
3267 render the current page of the form in the ``preview view``, fails. EXT:form
3268 uses this event to show an error message as a flash message and to show the
3269 received error text in the ``preview view``.
3270
3271 Subscribe to the event:
3272
3273 .. code-block:: javascript
3274
3275    /**
3276     * @private
3277     *
3278     * @param string
3279     * @param array
3280     *              args[0] = jqXHR
3281     *              args[1] = textStatus
3282     *              args[2] = errorThrown
3283     * @return void
3284     */
3285    getPublisherSubscriber().subscribe('core/ajax/error', function(topic, args) {
3286    });
3287
3288
3289 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-renderformdefinitionpage-success:
3290
3291 core/ajax/renderFormDefinitionPage/success
3292 ++++++++++++++++++++++++++++++++++++++++++
3293
3294 This event is called if the Ajax request that is used to render the current
3295 page of the form in the ``preview view`` was successful. EXT:form uses this
3296 event to display the rendered form in the ``preview view``.
3297
3298 Subscribe to the event:
3299
3300 .. code-block:: javascript
3301
3302    /**
3303     * @private
3304     *
3305     * @param string
3306     * @param array
3307     *              args[0] = html
3308     *              args[1] = pageIndex
3309     * @return void
3310     */
3311    getPublisherSubscriber().subscribe('core/ajax/renderFormDefinitionPage/success', function(topic, args) {
3312    });
3313
3314
3315 .. _apireference-formeditor-basicjavascriptconcepts-events-core-ajax-saveformdefinition-success:
3316
3317 core/ajax/saveFormDefinition/success
3318 ++++++++++++++++++++++++++++++++++++
3319
3320 This event is called if the Ajax request that is used to save the form was
3321 successful. EXT:form uses this event to display a success message as a flash
3322 message. The ``form editor`` is also informed that no unsaved content currently
3323 exists.
3324
3325 Subscribe to the event:
3326
3327 .. code-block:: javascript
3328
3329    /**
3330     * @private
3331     *
3332     * @param string
3333     * @param array
3334     *              args[0] = html
3335     * @return void
3336     */
3337    getPublisherSubscriber().subscribe('core/ajax/saveFormDefinition/success', function(topic, args) {
3338    });
3339
3340
3341 .. _apireference-formeditor-basicjavascriptconcepts-events-core-applicationstate-add:
3342
3343 core/applicationState/add
3344 +++++++++++++++++++++++++
3345
3346 The addition/ deletion and movement of form elements und property collection
3347 elements (validators/ finishers) is saved in an internal stack so that the
3348 undo/ redo function can be implemented. This event is called whenever the
3349 current state is added to the stack. EXT:form uses this event to reset the
3350 enabled/ disabled state of the undo/ redo buttons.
3351
3352 Subscribe to the event:
3353
3354 .. code-block:: javascript
3355
3356    /**
3357     * @private
3358     *
3359     * @param string
3360     * @param array
3361     *              args[0] = applicationState
3362     *              args[1] = stackPointer
3363     *              args[2] = stackSize
3364     * @return void
3365     */
3366    getPublisherSubscriber().subscribe('core/applicationState/add', function(topic, args) {
3367    });
3368
3369
3370 .. _apireference-formeditor-basicjavascriptconcepts-events-core-currentlyselectedformelementchanged:
3371
3372 core/currentlySelectedFormElementChanged
3373 ++++++++++++++++++++++++++++++++++++++++
3374
3375 The method ``getFormEditorApp().setCurrentlySelectedFormElement()`` tells the
3376 ``form editor`` which form element should currently be dealt with. This method
3377 calls this event at the end.
3378
3379 Subscribe to the event:
3380
3381 .. code-block:: javascript
3382
3383    /**
3384     * @private
3385     *
3386     * @param string
3387     * @param array
3388     *              args[0] = formElement
3389     * @return void
3390     */
3391    getPublisherSubscriber().subscribe('core/currentlySelectedFormElementChanged', function(topic, args) {
3392    });
3393
3394
3395 .. _apireference-formeditor-basicjavascriptconcepts-events-core-formelement-somepropertychanged:
3396
3397 core/formElement/somePropertyChanged
3398 ++++++++++++++++++++++++++++++++++++
3399
3400 Each :ref:`FormElement model<apireference-formeditor-basicjavascriptconcepts-formelementmodel>`
3401 can write properties into the ``FormElement model`` through the methods ``get``
3402 and ``set``. Each property path can register an event name for the publisher
3403 through the method ``on``. This event is then always called when a property
3404 path is written via ``set``. Read :ref:`FormElement model<concepts-formeditor-basicjavascriptconcepts-formelementmodel>`
3405 for more information. EXT:form automatically registers for all known property
3406 paths of a form element the event ``core/formElement/somePropertyChanged``.
3407 This means that every property written via ``set`` calls this event. Among
3408 other things, EXT:form uses this event for, for example, updating the label of
3409 a form element in other components (e.g. ``Tree`` component ) when this label
3410 is changed. Furthermore, any validation errors from form element properties
3411 are indicated by this event in the ``Tree`` component.
3412
3413 Subscribe to the event:
3414
3415 .. code-block:: javascript
3416
3417    /**
3418     * @private
3419     *
3420     * @param string
3421     * @param array
3422     *              args[0] = propertyPath
3423     *              args[1] = value
3424     *              args[2] = oldValue
3425     *              args[3] = formElementIdentifierPath
3426     * @return void
3427     */
3428    getPublisherSubscriber().subscribe('core/formElement/somePropertyChanged', function(topic, args) {
3429    });
3430
3431
3432 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-moved:
3433
3434 view/collectionElement/moved
3435 ++++++++++++++++++++++++++++
3436
3437 The method ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``
3438 calls this event at the end. EXT:form uses this event to re-render the
3439 ``Inspector`` component as soon as a property collection element (validator/
3440 finisher) is moved.
3441
3442 Subscribe to the event:
3443
3444 .. code-block:: javascript
3445
3446    /**
3447     * @private
3448     *
3449     * @param string
3450     * @param array
3451     *              args[0] = movedCollectionElementIdentifier
3452     *              args[1] = previousCollectionElementIdentifier
3453     *              args[2] = nextCollectionElementIdentifier
3454     *              args[3] = collectionName
3455     * @return void
3456     */
3457    getPublisherSubscriber().subscribe('view/collectionElement/moved', function(topic, args) {
3458    });
3459
3460
3461 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-new-added:
3462
3463 view/collectionElement/new/added
3464 ++++++++++++++++++++++++++++++++
3465
3466 The method ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``
3467 calls this event at the end. EXT:form uses this event to re-render the
3468 ``Inspector`` component as soon as a property collection element (validator/
3469 finisher) is created and added.
3470
3471 Subscribe to the event:
3472
3473 .. code-block:: javascript
3474
3475    /**
3476     * @private
3477     *
3478     * @param string
3479     * @param array
3480     *              args[0] = collectionElementIdentifier
3481     *              args[1] = collectionName
3482     *              args[2] = formElement
3483     *              args[3] = collectionElementConfiguration
3484     *              args[4] = referenceCollectionElementIdentifier
3485     * @return void
3486     */
3487    getPublisherSubscriber().subscribe('view/collectionElement/new/added', function(topic, args) {
3488    });
3489
3490
3491 .. _apireference-formeditor-basicjavascriptconcepts-events-view-collectionelement-removed:
3492
3493 view/collectionElement/removed
3494 ++++++++++++++++++++++++++++++
3495
3496 The method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``
3497 calls this event at the end. EXT:form uses this event to re-render the
3498 ``Inspector`` component as soon as a property collection element (validator/
3499 finisher) is removed.
3500
3501 Subscribe to the event:
3502
3503 .. code-block:: javascript
3504
3505    /**
3506     * @private
3507     *
3508     * @param string
3509     * @param array
3510     *              args[0] = collectionElementIdentifier
3511     *              args[1] = collectionName
3512     *              args[2] = formElement
3513     * @return void
3514     */
3515    getPublisherSubscriber().subscribe('view/collectionElement/removed', function(topic, args) {
3516    });
3517
3518
3519 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted:
3520
3521 view/formElement/inserted
3522 +++++++++++++++++++++++++
3523
3524 The method ``getFormEditorApp().getViewModel().createAndAddFormElement()`` and
3525 the event :ref:`view/insertElements/perform/after<apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after>`
3526 call this event at the end. EXT:form uses this event to set the current
3527 to-be-processed form element (``getFormEditorApp().setCurrentlySelectedFormElement()``)
3528 and to re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
3529
3530 Subscribe to the event:
3531
3532 .. code-block:: javascript
3533
3534    /**
3535     * @private
3536     *
3537     * @param string
3538     * @param array
3539     *              args[0] = newFormElement
3540     * @return void
3541     */
3542    getPublisherSubscriber().subscribe('view/formElement/inserted', function(topic, args) {
3543    });
3544
3545
3546 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-moved:
3547
3548 view/formElement/moved
3549 ++++++++++++++++++++++
3550
3551 The method ``getFormEditorApp().getViewModel().moveFormElement()`` calls this
3552 event at the end.
3553
3554 Subscribe to the event:
3555
3556 .. code-block:: javascript
3557
3558    /**
3559     * @private
3560     *
3561     * @param string
3562     * @param array
3563     *              args[0] = movedFormElement
3564     * @return void
3565     */
3566    getPublisherSubscriber().subscribe('view/formElement/moved', function(topic, args) {
3567    });
3568
3569
3570 .. _apireference-formeditor-basicjavascriptconcepts-events-view-formelement-removed:
3571
3572 view/formElement/removed
3573 ++++++++++++++++++++++++
3574
3575 The method ``getFormEditorApp().getViewModel().removeFormElement()`` calls this
3576 event at the end. EXT:form uses this event to set the current to-be-processed
3577 form element (``getFormEditorApp().setCurrentlySelectedFormElement()``) and to
3578 re-render the ``Tree``, ``Stage`` and ``Inspector`` components.
3579
3580 Subscribe to the event:
3581
3582 .. code-block:: javascript
3583
3584    /**
3585     * @private
3586     *
3587     * @param string
3588     * @param array
3589     *              args[0] = parentFormElement
3590     * @return void
3591     */
3592    getPublisherSubscriber().subscribe('view/formElement/removed', function(topic, args) {
3593    });
3594
3595
3596 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-close-clicked:
3597
3598 view/header/button/close/clicked
3599 ++++++++++++++++++++++++++++++++
3600
3601 The onClick event of the "Close" button in the ``form editor's`` header section
3602 calls this event. EXT:form uses this event to display a warning message in case
3603 there are unsaved changes.
3604
3605 Subscribe to the event:
3606
3607 .. code-block:: javascript
3608
3609    /**
3610     * @private
3611     *
3612     * @param string
3613     * @param array
3614     * @return void
3615     */
3616    getPublisherSubscriber().subscribe('view/header/button/close/clicked', function(topic, args) {
3617    });
3618
3619
3620 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-newpage-clicked:
3621
3622 view/header/button/newPage/clicked
3623 ++++++++++++++++++++++++++++++++++
3624
3625 The onClick event of the "new page" button in the ``form editor's`` header
3626 section calls this event. EXT:form uses this event to display the "new page"
3627 dialog box.
3628
3629 Subscribe to the event:
3630
3631 .. code-block:: javascript
3632
3633    /**
3634     * @private
3635     *
3636     * @param string
3637     * @param array
3638     *              args[0] = targetEvent
3639     * @return void
3640     */
3641    getPublisherSubscriber().subscribe('view/header/button/newPage/clicked', function(topic, args) {
3642    });
3643
3644
3645 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-button-save-clicked:
3646
3647 view/header/button/save/clicked
3648 +++++++++++++++++++++++++++++++
3649
3650 The onClick event of the "save" button in the ``form editor's`` header section
3651 calls this event. EXT:form uses this event either to display a dialog box with
3652 the element in question (if there are validation errors) or to save the ``form
3653 definition`` (if there are no validation errors).
3654
3655 Subscribe to the event:
3656
3657 .. code-block:: javascript
3658
3659    /**
3660     * @private
3661     *
3662     * @param string
3663     * @param array
3664     * @return void
3665     */
3666    getPublisherSubscriber().subscribe('view/header/button/save/clicked', function(topic, args) {
3667    });
3668
3669
3670 .. _apireference-formeditor-basicjavascriptconcepts-events-view-header-formsettings-clicked:
3671
3672 view/header/formSettings/clicked
3673 ++++++++++++++++++++++++++++++++
3674
3675 The onClick event of the "settings"  button in the ``form editor's`` header
3676 section calls this event. EXT:form uses this event to select the root form
3677 element.
3678
3679 Subscribe to the event:
3680
3681 .. code-block:: javascript
3682
3683    /**
3684     * @private
3685     *
3686     * @param string
3687     * @param array
3688     * @return void
3689     */
3690    getPublisherSubscriber().subscribe('view/header/formSettings/clicked', function(topic, args) {
3691    });
3692
3693
3694 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-after:
3695
3696 view/insertElements/perform/after
3697 +++++++++++++++++++++++++++++++++
3698
3699 This event is called from the "new element" dialog box upon selection of a form
3700 element:
3701
3702 - if "After" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
3703 - if the "Create new element" button in the form-element toolbar for non-composite elements is clicked.
3704
3705 EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``)
3706 and then move (``getFormEditorApp().getViewModel().moveFormElement()``) it
3707 below the currently selected element (sibling). At the end of this event, the
3708 event :ref:`view/formElement/inserted<apireference-formeditor-basicjavascriptconcepts-events-view-formelement-inserted>`
3709 is called. The event ``view/formElement/inserted`` in ``getFormEditorApp().getViewModel().createAndAddFormElement()``
3710 was previously deactivated.
3711
3712 Subscribe to the event:
3713
3714 .. code-block:: javascript
3715
3716    /**
3717     * @private
3718     *
3719     * @param string
3720     * @param array
3721     *              args[0] = formElementType
3722     * @return void
3723     */
3724    getPublisherSubscriber().subscribe('view/insertElements/perform/after', function(topic, args) {
3725    });
3726
3727
3728 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-bottom:
3729
3730 view/insertElements/perform/bottom
3731 ++++++++++++++++++++++++++++++++++
3732
3733 This event is called from the "new element" dialog box upon selection of a form
3734 element:
3735
3736 - if, in the ``abstract view`` mode, the "Create new element" button at the end of the ``Stage`` component is clicked.
3737
3738 EXT:form uses this event to create a new form element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3739 This element is always created as the last element of the currently selected
3740 page.
3741
3742 Subscribe to the event:
3743
3744 .. code-block:: javascript
3745
3746    /**
3747     * @private
3748     *
3749     * @param string
3750     * @param array
3751     *              args[0] = formElementType
3752     * @return void
3753     */
3754    getPublisherSubscriber().subscribe('view/insertElements/perform/bottom', function(topic, args) {
3755    });
3756
3757
3758 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertelements-perform-inside:
3759
3760 view/insertElements/perform/inside
3761 ++++++++++++++++++++++++++++++++++
3762
3763 This event is called from the "new element" dialog box upon selection of a form
3764 element:
3765
3766 - if "Inside" in the "Create new element" split button in the form-element toolbar for composite elements (e.g. fieldset) is clicked.
3767
3768 EXT:form uses this event to create a new form element as a child element of the
3769 currently selected element (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3770
3771 Subscribe to the event:
3772
3773 .. code-block:: javascript
3774
3775    /**
3776     * @private
3777     *
3778     * @param string
3779     * @param array
3780     *              args[0] = formElementType
3781     * @return void
3782     */
3783    getPublisherSubscriber().subscribe('view/insertElements/perform/inside', function(topic, args) {
3784    });
3785
3786
3787 .. _apireference-formeditor-basicjavascriptconcepts-events-view-insertpages-perform:
3788
3789 view/insertPages/perform
3790 ++++++++++++++++++++++++
3791
3792 This event is called from the "new element" dialog box upon selection of a page
3793 element:
3794
3795 - if the "Create new page" icon in the header section is clicked.
3796 - if the "Create new page" button in the ``Tree`` component is clicked.
3797
3798 EXT:form uses this event to create a new page after the currently selected page
3799 (``getFormEditorApp().getViewModel().createAndAddFormElement()``).
3800
3801 Subscribe to the event:
3802
3803 .. code-block:: javascript
3804
3805    /**
3806     * @private
3807     *
3808     * @param string
3809     * @param array
3810     *              args[0] = formElementType
3811     * @return void
3812     */
3813    getPublisherSubscriber().subscribe('view/insertPages/perform', function(topic, args) {
3814    });
3815
3816
3817 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-existing-selected:
3818
3819 view/inspector/collectionElement/existing/selected
3820 ++++++++++++++++++++++++++++++++++++++++++++++++++
3821
3822 The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
3823 and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
3824 are used to display the available validators/ finishers for a form element as a
3825 select box. Furthermore, these ``inspector editors`` indicate that in the
3826 ``form definition``, validators/ finishers for the currently selected element
3827 already exist. This occurs through the event ``view/inspector/collectionElement/existing/selected``.
3828 EXT:form uses this event to render these validators/ finishers and their
3829 tentatively configured ``inspector editors`` (``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``).
3830
3831 Subscribe to the event:
3832
3833 .. code-block:: javascript
3834
3835    /**
3836     * @private
3837     *
3838     * @param string
3839     * @param array
3840     *              args[0] = collectionElementIdentifier
3841     *              args[1] = collectionName
3842     * @return void
3843     */
3844    getPublisherSubscriber().subscribe('view/inspector/collectionElement/existing/selected', function(topic, args) {
3845    });
3846
3847
3848 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-new-selected:
3849
3850 view/inspector/collectionElement/new/selected
3851 +++++++++++++++++++++++++++++++++++++++++++++
3852
3853 The ``inspector editors`` :ref:`ValidatorsEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.finisherseditor>`
3854 and :ref:`FinishersEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.validatorseditor>`
3855 are used to display the available validators/ finishers for a form element as a
3856 select box. The onChange event of the select box then calls this event. In
3857 addition, the ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
3858 calls this event when a checkbox is chosen. EXT:form uses this event to add and
3859 render the validator/ finisher of the ``form definition`` via ``getFormEditorApp().getViewModel().createAndAddPropertyCollectionElement()``.
3860
3861 Subscribe to the event:
3862
3863 .. code-block:: javascript
3864
3865    /**
3866     * @private
3867     *
3868     * @param string
3869     * @param array
3870     *              args[0] = collectionElementIdentifier
3871     *              args[1] = collectionName
3872     * @return void
3873     */
3874    getPublisherSubscriber().subscribe('view/inspector/collectionElement/new/selected', function(topic, args) {
3875    });
3876
3877
3878 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-collectionelement-dnd-update:
3879
3880 view/inspector/collectionElements/dnd/update
3881 ++++++++++++++++++++++++++++++++++++++++++++
3882
3883 EXT:form uses the jQuery plugin 'jquery.mjs.nestedSortable' for the drag-and-
3884 drop functionality. The 'update' event from 'jquery.mjs.nestedSortable' calls
3885 the ``view/inspector/collectionElements/dnd/update`` event if a property
3886 collection element in the ``Inspector`` component is sorted. EXT:form uses this
3887 event to move the validator/ finisher in the ``form definition`` via the method
3888 ``getFormEditorApp().getViewModel().movePropertyCollectionElement()``.
3889
3890 Subscribe to the event:
3891
3892 .. code-block:: javascript
3893
3894    /**
3895     * @private
3896     *
3897     * @param string
3898     * @param array
3899     *              args[0] = movedCollectionElementIdentifier
3900     *              args[1] = previousCollectionElementIdentifier
3901     *              args[2] = nextCollectionElementIdentifier
3902     *              args[3] = collectionName
3903     * @return void
3904     */
3905    getPublisherSubscriber().subscribe('view/inspector/collectionElements/dnd/update', function(topic, args) {
3906    });
3907
3908
3909 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-editor-insert-perform:
3910
3911 view/inspector/editor/insert/perform
3912 ++++++++++++++++++++++++++++++++++++
3913
3914 The methods ``getFormEditorApp().getViewModel().renderInspectorEditors()`` (to
3915 render all ``inspector editors`` for a form element) and ``getFormEditorApp().getViewModel().renderInspectorCollectionElementEditors()``
3916 (to render the ``inspector editors`` for a validator/ finisher) call this event
3917 at the end. Strictly speaking, the ``Inspector`` component in the method
3918 ``_renderEditorDispatcher()`` calls this event.
3919 Each ``inspector editor`` has the property :ref:`templateName <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.templatename>`,
3920 which gives the ``form editor`` two pieces of information. On the one hand the
3921 ``templateName`` must match with a key within the :ref:`TYPO3.CMS.Form.prototypes.\<prototypeIdentifier>.formeditor.formEditorPartials <typo3.cms.form.prototypes.\<prototypeidentifier>.formeditor.formeditorpartials>`.
3922 The ``form editor`` can consequently load a corresponding inline HTML template
3923 for the ``inspector editor``. On the other hand, the ``Inspector`` component
3924 must be told which JavaScript code should be executed for the
3925 ``inspector editor``. For the ``inspector editors`` delivered with EXT:form,
3926 this occurs within the method ``_renderEditorDispatcher()``.
3927 An existing hard-coded list of known ``inspector editors`` determines, by means
3928 of the property ``templateName``, which corresponding JavaScript method should
3929 be executed for the ``inspector editor``. At the end, the event
3930 ``view/inspector/editor/insert/perform`` is called. If you wish to implement
3931 your own ``inspector editor``, you can use this event to execute in
3932 :ref:`your own JavaScript module <concepts-formeditor-basicjavascriptconcepts-registercustomjavascriptmodules>`.
3933 the corresponding JavaScript code, with the help of the property
3934 ``templateName``.
3935
3936 Subscribe to the event:
3937
3938 .. code-block:: javascript
3939
3940    /**
3941     * @private
3942     *
3943     * @param string
3944     * @param array
3945     *              args[0] = editorConfiguration
3946     *              args[1] = editorHtml
3947     *              args[2] = collectionElementIdentifier
3948     *              args[3] = collectionName
3949     * @return void
3950     */
3951    getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
3952    });
3953
3954
3955 A simple example that registers a custom ``inspector editor`` called 'Inspector-MyCustomInspectorEditor' and adds it to text form elements:
3956
3957 .. code-block:: yaml
3958
3959    TYPO3:
3960      CMS:
3961        Form:
3962          prototypes:
3963            standard:
3964              formEditor:
3965                dynamicRequireJsModules:
3966                  additionalViewModelModules:
3967                    10: 'TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel'
3968                formEditorFluidConfiguration:
3969                  partialRootPaths:
3970                    100: 'EXT:my_site_package/Resources/Private/Backend/Partials/FormEditor/'
3971                formEditorPartials:
3972                  Inspector-MyCustomInspectorEditor: 'Inspector/MyCustomInspectorEditor'
3973              formElementsDefinition:
3974                Text:
3975                  formEditor:
3976                    editors:
3977                      600:
3978                        templateName: 'Inspector-MyCustomInspectorEditor'
3979                        ...
3980
3981
3982 .. code-block:: javascript
3983    :emphasize-lines: 107-116
3984
3985    /**
3986     * Module: TYPO3/CMS/MySitePackage/Backend/FormEditor/ViewModel
3987     */
3988    define(['jquery',
3989            'TYPO3/CMS/Form/Backend/FormEditor/Helper'
3990            ], function($, Helper) {
3991            'use strict';
3992
3993        return (function($, Helper) {
3994
3995            /**
3996             * @private
3997             *
3998             * @var object
3999             */
4000            var _formEditorApp = null;
4001
4002            /**
4003             * @private
4004             *
4005             * @return object
4006             */
4007            function getFormEditorApp() {
4008                return _formEditorApp;
4009            };
4010
4011            /**
4012             * @private
4013             *
4014             * @return object
4015             */
4016            function getPublisherSubscriber() {
4017                return getFormEditorApp().getPublisherSubscriber();
4018            };
4019
4020            /**
4021             * @private
4022             *
4023             * @return object
4024             */
4025            function getUtility() {
4026                return getFormEditorApp().getUtility();
4027            };
4028
4029            /**
4030             * @private
4031             *
4032             * @param object
4033             * @return object
4034             */
4035            function getHelper() {
4036                return Helper;
4037            };
4038
4039            /**
4040             * @private
4041             *
4042             * @return object
4043             */
4044            function getCurrentlySelectedFormElement() {
4045                return getFormEditorApp().getCurrentlySelectedFormElement();
4046            };
4047
4048            /**
4049             * @private
4050             *
4051             * @param mixed test
4052             * @param string message
4053             * @param int messageCode
4054             * @return void
4055             */
4056            function assert(test, message, messageCode) {
4057                return getFormEditorApp().assert(test, message, messageCode);
4058            };
4059
4060            /**
4061             * @private
4062             *
4063             * @return void
4064             * @throws 1491643380
4065             */
4066            function _helperSetup() {
4067                assert('function' === $.type(Helper.bootstrap),
4068                    'The view model helper does not implement the method "bootstrap"',
4069                    1491643380
4070                );
4071                Helper.bootstrap(getFormEditorApp());
4072            };
4073
4074            /**
4075             * @private
4076             *
4077             * @return void
4078             */
4079            function _subscribeEvents() {
4080                /**
4081                 * @private
4082                 *
4083                 * @param string
4084                 * @param array
4085                 *              args[0] = editorConfiguration
4086                 *              args[1] = editorHtml
4087                 *              args[2] = collectionElementIdentifier
4088                 *              args[3] = collectionName
4089                 * @return void
4090                 */
4091                getPublisherSubscriber().subscribe('view/inspector/editor/insert/perform', function(topic, args) {
4092                    if (args[0]['templateName'] === 'Inspector-MyCustomInspectorEditor') {
4093                        renderMyCustomInspectorEditor(
4094                            args[0],
4095                            args[1],
4096                            args[2],
4097                            args[3]
4098                        );
4099                    }
4100                });
4101            };
4102
4103            /**
4104             * @private
4105             *
4106             * @param object editorConfiguration
4107             * @param object editorHtml
4108             * @param string collectionElementIdentifier
4109             * @param string collectionName
4110             * @return void
4111             */
4112            function renderMyCustomInspectorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
4113                // do cool stuff
4114            });
4115
4116            /**
4117             * @public
4118             *
4119             * @param object formEditorApp
4120             * @return void
4121             */
4122            function bootstrap(formEditorApp) {
4123                _formEditorApp = formEditorApp;
4124                _helperSetup();
4125                _subscribeEvents();
4126            };
4127
4128            /**
4129             * Publish the public methods.
4130             * Implements the "Revealing Module Pattern".
4131             */
4132            return {
4133                bootstrap: bootstrap
4134            };
4135        })($, Helper);
4136    });
4137
4138
4139 .. _apireference-formeditor-basicjavascriptconcepts-events-view-inspector-removecollectionelement-perform:
4140
4141 view/inspector/removeCollectionElement/perform
4142 ++++++++++++++++++++++++++++++++++++++++++++++
4143
4144 The ``inspector editor`` :ref:`RequiredValidatorEditor <typo3.cms.form.prototypes.\<prototypeidentifier>.formelementsdefinition.\<formelementtypeidentifier>.formeditor.editors.*.requiredvalidatoreditor>`
4145 calls this event, if the checkbox is deselected. EXT:form uses this event to
4146 remove the configured required validator ('NotEmpty') from the ``form
4147 definition`` through the method ``getFormEditorApp().getViewModel().removePropertyCollectionElement()``.
4148
4149 Subscribe to the event:
4150
4151 .. code-block:: javascript
4152
4153    /**
4154     * @private
4155     *
4156     * @param string
4157     * @param array
4158     *              args[0] = collectionElementIdentifier
4159     *              args[1] = collectionName
4160     *              args[2] = formElement
4161     * @return void
4162     */
4163    getPublisherSubscriber().subscribe('view/inspector/removeCollectionElement/perform', function(topic, args) {
4164    });
4165
4166
4167 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-close-perform:
4168
4169 view/modal/close/perform
4170 ++++++++++++++++++++++++
4171
4172 If you try to close the ``form editor`` with unsaved content, a dialog box
4173 appears, asking whether you really wish to close it. If you confirm it, this
4174 event is called in the ``check box`` component. EXT:form uses this event to
4175 close the ``form editor`` and return to the ``form manager``.
4176
4177 Subscribe to the event:
4178
4179 .. code-block:: javascript
4180
4181    /**
4182     * @private
4183     *
4184     * @param string
4185     * @param array
4186     * @return void
4187     */
4188    getPublisherSubscriber().subscribe('view/modal/close/perform', function(topic, args) {
4189    });
4190
4191
4192 .. _apireference-formeditor-basicjavascriptconcepts-events-view-modal-removecollectionelement-perform:
4193
4194 view/modal/removeCollectionElement/perform
4195 ++++++++++++++++++++++++++++++++++++++++++
4196
4197 If you try to remove a validator/ finisher by clicking the remove icon, a
4198 dialog box appears, asking you to confirm this action. If confirmed, this event
4199 is called in the ``check box`` component. EXT:form uses this event to remove
4200 the validator/ finisher from the ``form definition`` through the method