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