TYPO3 v15 dev-main snapshot ()

This commit is contained in:
2026-08-10 22:31:24 +02:00
commit aad9daaefd
1506 changed files with 94005 additions and 0 deletions
+171
View File
@@ -0,0 +1,171 @@
.. include:: /Includes.rst.txt
.. _apireference-events:
.. _apireference-formeditor-events:
.. _apireference-formeditor-hooks-beforeformcreate:
.. _apireference-formeditor-hooks-beforeformcreate-connect:
.. _apireference-formeditor-hooks-beforeformcreate-use:
.. _apireference-formeditor-events-beforeformiscreatedevent:
.. _apireference-formeditor-hooks-beforeformduplicate:
.. _apireference-formeditor-hooks-beforeformduplicate-connect:
.. _apireference-formeditor-hooks-beforeformduplicate-use:
.. _apireference-formeditor-hooks-beforeformdelete:
.. _apireference-formeditor-hooks-beforeformdelete-connect:
.. _apireference-formeditor-hooks-beforeformdelete-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks:
.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement:
.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-initializeformelement-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforeremovefromparentrenderable-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterbuildingfinished-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-afterinitializecurrentpage-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit:
.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-aftersubmit-use:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-connect:
.. _apireference-frontendrendering-runtimemanipulation-hooks-beforerendering-use:
.. _apireference-events-legacy-hooks-buildformvalidationconfiguration:
.. _apireference-events-legacy-hooks-afterformstateinitialized:
.. _apireference-events-legacy-hooks:
================
PSR-14 Events
================
EXT:form dispatches PSR-14 events at key points in the lifecycle of a form
both in the backend form editor and during frontend rendering. These events
are the recommended extension point for developers; the legacy
:php:`$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']` hooks have been removed.
.. seealso::
The canonical, always-up-to-date reference for all EXT:form events lives
in the TYPO3 Core API documentation:
`Form <https://docs.typo3.org/permalink/t3coreapi:eventlist-form>`_
The extension documentation below provides context, usage notes and
quick navigation; it intentionally avoids duplicating the full API
reference.
.. contents::
:depth: 1
:local:
.. _apireference-events-backend:
Backend events (form editor / manager)
=======================================
These events are dispatched when an editor creates, saves, duplicates or
deletes a form definition in the TYPO3 backend.
.. _apireference-events-backend-table:
.. list-table::
:header-rows: 1
:widths: 40 60
* - Event
- When / what can be modified
* - `BeforeFormIsCreatedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforeformiscreatedevent>`_
- Modify the form definition array and/or the persistence identifier
before a new form is created in the backend.
* - `BeforeFormIsSavedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforeformissavedevent>`_
- Modify the form definition array and/or the persistence identifier
before a form is saved in the backend.
* - `BeforeFormIsDuplicatedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforeformisduplicatedevent>`_
- Modify the form definition array and/or the persistence identifier
of the copy before a form is duplicated.
* - `BeforeFormIsDeletedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforeformisdeletedevent>`_
- Dispatched before a form is deleted. Set
:php:`$event->preventDeletion = true` to abort the deletion (the
event implements :php:`StoppableEventInterface`).
.. _apireference-events-frontend:
Frontend events (form rendering / runtime)
==========================================
These events are dispatched during form rendering in the frontend.
.. _apireference-events-frontend-table:
.. list-table::
:header-rows: 1
:widths: 40 60
* - Event
- When / what can be modified
* - `AfterFormIsBuiltEvent
<https://docs.typo3.org/permalink/t3coreapi:afterformisbuiltevent>`_
- Modify the :php:`FormDefinition` object after the form factory has
finished building the complete form.
* - `BeforeRenderableIsAddedToFormEvent
<https://docs.typo3.org/permalink/t3coreapi:beforerenderableisaddedtoformevent>`_
- Modify or replace a renderable (page, section or element) before it
is added to the form tree.
* - `BeforeRenderableIsRemovedFromFormEvent
<https://docs.typo3.org/permalink/t3coreapi:beforerenderableisremovedfromformevent>`_
- Dispatched before a renderable is removed from the form tree. Set
:php:`$event->preventRemoval = true` to abort the removal (the
event implements :php:`StoppableEventInterface`).
* - `AfterCurrentPageIsResolvedEvent
<https://docs.typo3.org/permalink/t3coreapi:aftercurrentpageisresolvedevent>`_
- Override :php:`$event->currentPage` after the current page has been
resolved from the request, e.g. to implement conditional page-skip
logic.
* - `BeforeRenderableIsValidatedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforerenderableisvalidatedevent>`_
- Modify :php:`$event->value` before property-mapping and validation
run for each submitted form element.
* - `BeforeRenderableIsRenderedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforerenderableisrenderedevent>`_
- Modify the renderable or the :php:`FormRuntime` just before a
renderable is output to the browser.
* - `BeforeEmailFinisherInitializedEvent
<https://docs.typo3.org/permalink/t3coreapi:beforeemailfinisherinitializedevent>`_
- Modify the options used by the :php:`EmailFinisher` (e.g. recipients,
subject) before they are applied.
* - `AfterFormStateInitializedEvent
<https://docs.typo3.org/permalink/t3coreapi:afterformstateinitializedevent>`_
- Enrich components with runtime data after the :php:`FormState` has
been restored from the request (form state and form session are
both available at this point).
* - `AfterFormDefinitionLoadedEvent
<https://docs.typo3.org/permalink/t3coreapi:afterformdefinitionloadedevent>`_
- Dispatched by :php:`FormPersistenceManager` after a YAML form
definition has been loaded from disk. Modify the definition globally
before it reaches the form factory.
* - `AfterFormDefinitionValidationConfigurationIsBuiltEvent
<https://docs.typo3.org/permalink/t3coreapi:afterformdefinitionvalidationconfigurationisbuiltevent>`_
- Dispatched after the form definition validation configuration has
been built from the form editor setup. Add additional writable
property paths for custom inspector editor implementations.
.. _apireference-events-register:
Registering an event listener
==============================
Register a listener via the :php:`#[AsEventListener]` PHP attribute:
.. literalinclude:: _codesnippets/_MyFormEventListener.php
:language: php
:caption: EXT:my_extension/Classes/EventListener/MyFormEventListener.php
.. seealso::
:ref:`t3coreapi:EventDispatcher` TYPO3 Core API documentation on how to
register and implement PSR-14 event listeners.
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace MyVendor\MyExtension\EventListener;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Form\Event\BeforeFormIsSavedEvent;
#[AsEventListener(
identifier: 'my-extension/before-form-is-saved',
)]
final readonly class MyFormEventListener
{
public function __invoke(BeforeFormIsSavedEvent $event): void
{
// Enrich the form definition before it is persisted
$event->form['renderingOptions']['myCustomOption'] = 'value';
}
}
@@ -0,0 +1,182 @@
.. include:: /Includes.rst.txt
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel:
.. _apireference-formeditor-formelementmodel:
==================
FormElement model
==================
Every form element in the editor is represented by a **FormElement model**
object. This model is the single source of truth for all element properties
during an editing session; it is separate from the YAML form definition on
disk (which is only written on save).
.. contents::
:depth: 1
:local:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-identifierpath:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-property-parentrenderable:
.. _apireference-formeditor-formelementmodel-structure:
Model structure
===============
A FormElement model carries all YAML properties of the element plus two
internal bookkeeping properties:
.. list-table::
:header-rows: 1
:widths: 30 70
* - Property
- Description
* - :js:`__identifierPath`
- Slash-separated path from the root element to this element
(e.g. :js:`'example-form/page-1/name'`). Used as a unique key
for API lookups.
* - :js:`__parentRenderable`
- Reference to the parent FormElement model (filtered for display).
Example model in memory:
.. literalinclude:: _codesnippets/_model-structure.js
:language: javascript
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-propertycollectionproperties:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-get-renderables:
.. _apireference-formeditor-formelementmodel-api-get:
get()
-----
Reads a property by its dot-separated path. All intermediate levels must
be objects.
.. literalinclude:: _codesnippets/_get-simple.js
:language: javascript
For **property collections** (validators / finishers), whose position in
the array is unknown, use :js:`buildPropertyPath()` first:
.. literalinclude:: _codesnippets/_get-property-collection.js
:language: javascript
For **renderables** (child elements), :js:`get('renderables')` returns a
plain array of FormElement models. To access a specific child, use
:js:`formEditorApp.getFormElementByIdentifierPath()` with the full path.
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-propertycollectionproperties:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-set-renderables:
.. _apireference-formeditor-formelementmodel-api-set:
set()
-----
Writes a property by its dot-separated path. Every :js:`set()` call
automatically publishes all events registered for that path via
:ref:`on() <apireference-formeditor-formelementmodel-api-on>`, including
the built-in
:ref:`core/formElement/somePropertyChanged <apireference-formeditor-jsevents-core-formelement-somepropertychanged>`.
.. literalinclude:: _codesnippets/_set.js
:language: javascript
To modify property collection properties or add child renderables, use
the dedicated API methods on :js:`formEditorApp` / :js:`getViewModel()`
instead of setting array positions directly:
- :js:`createAndAddFormElement()`
- :js:`addFormElement()`
- :js:`moveFormElement()`
- :js:`removeFormElement()`
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-propertycollectionproperties:
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-unset-renderables:
.. _apireference-formeditor-formelementmodel-api-unset:
unset()
-------
Removes a property at the given dot-separated path.
.. literalinclude:: _codesnippets/_unset.js
:language: javascript
For property collection properties, use :js:`buildPropertyPath()` in the
same way as for :ref:`get() <apireference-formeditor-formelementmodel-api-get>`.
To remove a child renderable, call
:js:`formEditorApp.removeFormElement()`.
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-on:
.. _apireference-formeditor-formelementmodel-api-on:
on()
----
Registers an additional publish/subscribe event name that is fired
whenever :js:`set()` is called for a given property path.
.. literalinclude:: _codesnippets/_on.js
:language: javascript
By default EXT:form registers
:ref:`core/formElement/somePropertyChanged <apireference-formeditor-jsevents-core-formelement-somepropertychanged>`
for every known property path of every form element.
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-off:
.. _apireference-formeditor-formelementmodel-api-off:
off()
-----
Removes an event registration created with :js:`on()`.
.. literalinclude:: _codesnippets/_off.js
:language: javascript
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-getobjectdata:
.. _apireference-formeditor-formelementmodel-api-getobjectdata:
getObjectData()
---------------
Returns a deep-cloned plain object of all properties. Used internally for
Ajax serialisation. Provides read access to data set via :js:`set()` from
outside the model without breaking encapsulation.
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-clone:
.. _apireference-formeditor-formelementmodel-api-clone:
clone()
-------
Returns a fully dereferenced clone of the FormElement model.
.. literalinclude:: _codesnippets/_clone.js
:language: javascript
.. _apireference-formeditor-basicjavascriptconcepts-formelementmodel-method-tostring:
.. _apireference-formeditor-formelementmodel-api-tostring:
toString()
----------
Returns the model data as a JSON string. Intended for debugging.
.. literalinclude:: _codesnippets/_to-string.js
:language: javascript
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
const formElement = formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name');
const copy = formElement.clone();
}
@@ -0,0 +1,10 @@
export function bootstrap(formEditorApp) {
const formElement = formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name');
const propertyPath = formEditorApp
.buildPropertyPath('options.minimum', 'StringLength', 'validators', formElement);
// propertyPath = e.g. 'validators.0.options.minimum'
const value = formElement.get(propertyPath); // '1'
}
@@ -0,0 +1,6 @@
export function bootstrap(formEditorApp) {
// Returns 'Name'
const placeholder = formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name')
.get('properties.fluidAdditionalAttributes.placeholder');
}
@@ -0,0 +1,19 @@
// Illustrative snapshot of a FormElement model as it exists in memory at runtime.
// The actual object is managed by the FormElement class access it via
// formEditorApp.getFormElementByIdentifierPath() and the get()/set() API.
export const formElementSnapshot = {
identifier: 'name',
defaultValue: '',
label: 'Name',
type: 'Text',
properties: {
fluidAdditionalAttributes: {
placeholder: 'Name',
},
},
__parentRenderable: 'example-form/page-1 (filtered)',
__identifierPath: 'example-form/page-1/name',
validators: [
{ identifier: 'NotEmpty' },
],
};
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name')
.off('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
}
@@ -0,0 +1,9 @@
export function bootstrap(formEditorApp) {
const element = formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name');
element.on('properties.fluidAdditionalAttributes.placeholder', 'my/custom/event');
// The next set() on that path will also publish 'my/custom/event'.
element.set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
}
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name')
.set('properties.fluidAdditionalAttributes.placeholder', 'New Placeholder');
}
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
const formElement = formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name');
console.log(formElement.toString());
}
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
formEditorApp
.getFormElementByIdentifierPath('example-form/page-1/name')
.unset('properties.fluidAdditionalAttributes.placeholder');
}
+97
View File
@@ -0,0 +1,97 @@
.. include:: /Includes.rst.txt
.. _apireference-formeditor:
.. _apireference-formeditor-basicjavascriptconcepts:
.. _apireference-formeditor-basicjavascriptconcepts-events:
.. _apireference-formeditor-stage:
===========
Form Editor
===========
This chapter is the developer reference for the TYPO3 backend form editor.
It covers the JavaScript extension points and the data model used by the
editor's TypeScript modules.
.. contents::
:depth: 1
:local:
.. _apireference-formeditor-architecture:
Architecture overview
=====================
The form editor consists of four cooperating TypeScript modules, each
responsible for one UI component:
.. list-table::
:header-rows: 1
:widths: 30 35 35
* - Module (import path)
- Component
- Responsibility
* - :js:`@typo3/form/backend/form-editor/view-model`
- —
- Central view model; wires DOM events and publishes/subscribes
to all cross-component events.
* - :js:`@typo3/form/backend/form-editor/stage-component`
- **Stage**
- Renders the abstract and preview views of the current form page.
* - :js:`@typo3/form/backend/form-editor/inspector-component`
- **Inspector**
- Renders the property editors for the selected form element.
* - :js:`@typo3/form/backend/form-editor/tree-component-adapter`
- **Structure tree**
- Wraps the TYPO3 backend tree web component and bridges its
events to the publish/subscribe bus.
* - :js:`@typo3/form/backend/form-editor/mediator`
- —
- Wires all publish/subscribe events to view-model actions.
Loaded automatically; replace via
:yaml:`dynamicJavaScriptModules.mediator` only when you need to
completely swap the event-wiring logic.
All modules communicate exclusively via a **publish/subscribe bus**
(:js:`PublisherSubscriber`). Direct module-to-module calls are avoided
so that extension code can hook into any point without modifying core
files.
.. _apireference-formeditor-custom-modules:
Registering a custom JavaScript module
=======================================
Custom modules must export a :js:`bootstrap` function. The form editor
calls this function once all built-in modules have loaded, passing the
central :js:`FormEditor` application object as the sole argument.
.. rst-class:: bignums-xxl
1. Create the JavaScript module
.. literalinclude:: _codesnippets/_bootstrap.js
:language: javascript
:caption: EXT:my_extension/Resources/Public/JavaScript/backend/form-editor/view-model.js
2. Register the module in the importmap
.. literalinclude:: _codesnippets/_JavaScriptModules.php
:language: php
:caption: EXT:my_extension/Configuration/JavaScriptModules.php
3. Tell the form editor to load the module
.. literalinclude:: _codesnippets/_prototype-setup.yaml
:language: yaml
:caption: EXT:my_extension/Configuration/Form/MyFormSet/config.yaml
.. toctree::
:maxdepth: 1
JavaScriptEvents/Index
StageTemplates/Index
FormElementModel/Index
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,22 @@
export function bootstrap(formEditorApp) {
formEditorApp.getPublisherSubscriber().subscribe(
'view/inspector/editor/insert/perform',
(topic, args) => {
const [editorConfiguration, editorHtml] = args;
if (editorConfiguration.templateName !== 'Inspector-MyCustomEditor') {
return;
}
// Wire up your custom editor UI inside editorHtml
const input = editorHtml.querySelector('.my-custom-input');
if (input) {
input.addEventListener('change', (e) => {
formEditorApp
.getCurrentlySelectedFormElement()
.set(editorConfiguration.propertyPath, e.target.value);
});
}
},
);
}
@@ -0,0 +1,18 @@
prototypes:
standard:
formEditor:
dynamicJavaScriptModules:
additionalViewModelModules:
10: '@vendor/my-extension/backend/form-editor/view-model.js'
formEditorPartials:
Inspector-MyCustomEditor: 'Inspector/MyCustomEditor'
formEditorFluidConfiguration:
partialRootPaths:
100: 'EXT:my_extension/Resources/Private/Backend/Partials/FormEditor/'
formElementsDefinition:
Text:
formEditor:
editors:
600:
templateName: 'Inspector-MyCustomEditor'
myOption: 'example'
@@ -0,0 +1,3 @@
export function bootstrap(formEditorApp) {
formEditorApp.getPublisherSubscriber().publish('my/custom/event', ['arg1', 'arg2']);
}
@@ -0,0 +1,11 @@
export function bootstrap(formEditorApp) {
formEditorApp.getPublisherSubscriber().subscribe(
'core/formElement/somePropertyChanged',
(topic, args) => {
const [propertyPath, newValue, oldValue, identifierPath] = args;
if (propertyPath === 'label' && identifierPath?.startsWith('my-form/page-1/')) {
console.log('Label changed from', oldValue, 'to', newValue);
}
},
);
}
@@ -0,0 +1,4 @@
<div class="formeditor-element-body">
<div data-identifier="elementLabel"></div>
<div data-identifier="elementSummary"></div>
</div>
@@ -0,0 +1,24 @@
export function bootstrap(formEditorApp) {
formEditorApp.getPublisherSubscriber().subscribe(
'view/stage/abstract/render/template/perform',
(topic, args) => {
const [formElement, template] = args;
if (formElement.get('type') !== 'MyCustomElement') {
return;
}
const labelEl = template.querySelector('[data-identifier="elementLabel"]');
if (labelEl) {
labelEl.textContent =
formElement.get('label') || formElement.get('identifier');
}
const summaryEl = template.querySelector('[data-identifier="elementSummary"]');
if (summaryEl) {
summaryEl.textContent =
formElement.get('properties.myCustomProperty') ?? '';
}
},
);
}
@@ -0,0 +1,11 @@
prototypes:
standard:
formEditor:
dynamicJavaScriptModules:
additionalViewModelModules:
10: '@vendor/my-extension/backend/form-editor/view-model.js'
formEditorPartials:
FormElement-MyCustomElement: 'Stage/MyCustomElement'
formEditorFluidConfiguration:
partialRootPaths:
100: 'EXT:my_extension/Resources/Private/Backend/Partials/FormEditor/'
@@ -0,0 +1,11 @@
export function bootstrap(formEditorApp) {
const ps = formEditorApp.getPublisherSubscriber();
// Subscribe returns a token for later unsubscription
const token = ps.subscribe('view/ready', (topic, args) => {
// args is a typed tuple matching the event signature
});
// Unsubscribe
ps.unsubscribe(token);
}
@@ -0,0 +1,5 @@
export function bootstrap(formEditorApp) {
formEditorApp.getPublisherSubscriber().subscribe('view/ready', () => {
// Safe to call any formEditorApp API here.
});
}
@@ -0,0 +1,137 @@
.. include:: /Includes.rst.txt
.. _apireference-formeditor-stage-commonabstractformelementtemplates:
.. _apireference-formeditor-stagetemplates:
===============
Stage templates
===============
The **Stage** component renders each form element as an HTML item in the
abstract view. This section explains the two rendering strategies: the
modern web-component approach (recommended) and the legacy Fluid-partial
approach (deprecated).
.. contents::
:depth: 1
:local:
.. _apireference-formeditor-stagetemplates-webcomponent:
Built-in web component (recommended)
=====================================
When no :yaml:`formEditorPartials` entry exists for a form element type,
the Stage component automatically renders it using the built-in
:html:`<typo3-form-form-element-stage-item>` web component. The component
displays the element's label, type icon, validators, select options and
allowed MIME types without requiring any custom JavaScript.
.. tip::
For most custom form elements this is the recommended approach. Simply
omit :yaml:`formEditorPartials` from the prototype configuration and the
editor handles the rest.
Properties set on the web component from the :js:`FormElement` model:
.. list-table::
:header-rows: 1
:widths: 30 70
* - Property
- Source in FormElement model
* - :js:`elementType`
- Form element definition :yaml:`label`
* - :js:`elementLabel`
- :yaml:`label` (falls back to :yaml:`identifier`)
* - :js:`elementIconIdentifier`
- Form element definition :yaml:`iconIdentifier`
* - :js:`validators`
- :yaml:`validators` array (excludes ``NotEmpty``, shown via :js:`isRequired`)
* - :js:`isRequired`
- ``true`` when a ``NotEmpty`` validator is present
* - :js:`options`
- :yaml:`properties.options` (for select-like elements)
* - :js:`allowedMimeTypes`
- :yaml:`properties.allowedMimeTypes`
* - :js:`content`
- :yaml:`properties.text` or :yaml:`properties.contentElementUid`
* - :js:`isHidden`
- ``true`` when :yaml:`renderingOptions.enabled` is ``false``
.. _apireference-formeditor-stagetemplates-fluid:
Custom Fluid partial (advanced)
================================
If you need fully custom stage rendering for example to display a
proprietary summary of complex properties you can still provide a Fluid
partial and subscribe to the
:ref:`view/stage/abstract/render/template/perform <apireference-formeditor-jsevents-view-stage-abstract-render-template-perform>`
event to populate it with DOM manipulation.
The core Fluid partials are located in
:file:`EXT:form/Resources/Private/Backend/Partials/FormEditor/Stage/`.
.. warning::
The legacy stage rendering helpers
:js:`renderSimpleTemplateWithValidators()` and
:js:`renderSelectTemplates()` from
:js:`@typo3/form/backend/form-editor/stage-component` are deprecated
since TYPO3 v14.2 and will be removed in TYPO3 v15. Migrate to the
web component approach (omit :yaml:`formEditorPartials`) or implement
custom DOM manipulation in the event subscriber.
.. _apireference-formeditor-stage-commonabstractformelementtemplates-simpletemplate:
.. _apireference-formeditor-stagetemplates-fluid-simpletemplate:
Stage/SimpleTemplate (deprecated)
----------------------------------
Displays the element :yaml:`label`. When the element has validators, a
validator icon and their labels appear on hover/selection. Rendered via
the deprecated :js:`renderSimpleTemplateWithValidators()`.
.. deprecated:: 14.2
Use the :html:`<typo3-form-form-element-stage-item>` web component
by omitting :yaml:`formEditorPartials`, or implement custom DOM
manipulation in the
:ref:`view/stage/abstract/render/template/perform <apireference-formeditor-jsevents-view-stage-abstract-render-template-perform>`
subscriber. See Deprecation :issue:`109306`.
.. _apireference-formeditor-stage-commonabstractformelementtemplates-selecttemplate:
.. _apireference-formeditor-stagetemplates-fluid-selecttemplate:
Stage/SelectTemplate (deprecated)
----------------------------------
Extends ``Stage/SimpleTemplate`` by additionally listing the chosen option
labels from :yaml:`properties.options.*`. Rendered via the deprecated
:js:`renderSelectTemplates()`.
Example form element using select options:
.. literalinclude:: _codesnippets/_select-template.yaml
:language: yaml
The template partial contains a container with the path to read:
.. literalinclude:: _codesnippets/_select-template-partial.html
:language: html
For elements using a different array property (e.g. ``FileUpload`` with
:yaml:`properties.allowedMimeTypes`), adjust the :html:`data-template-property`
attribute accordingly:
.. literalinclude:: _codesnippets/_file-upload-partial.html
:language: html
The web component handles both cases automatically.
.. deprecated:: 14.2
Use the :html:`<typo3-form-form-element-stage-item>` web component
by omitting :yaml:`formEditorPartials`.
See `Deprecation: #109306 - Deprecate form editor stage template rendering functions <https://docs.typo3.org/permalink/changelog:deprecation-109306-1774010043>`_.
@@ -0,0 +1,2 @@
<div data-identifier="multiValueContainer"
data-template-property="properties.allowedMimeTypes"></div>
@@ -0,0 +1,2 @@
<div data-identifier="multiValueContainer"
data-template-property="properties.options"></div>
@@ -0,0 +1,7 @@
type: MultiCheckbox
identifier: multicheckbox-1
label: 'Multi checkbox'
properties:
options:
value1: label1
value2: label2
@@ -0,0 +1,9 @@
<?php
return [
'dependencies' => ['form'],
'imports' => [
'@vendor/my-extension/'
=> 'EXT:my_extension/Resources/Public/JavaScript/',
],
];
@@ -0,0 +1,10 @@
/**
* Custom form editor module for EXT:my_extension.
*/
export function bootstrap(formEditorApp) {
const ps = formEditorApp.getPublisherSubscriber();
ps.subscribe('view/ready', () => {
// Editor is fully initialised set up your custom logic here.
});
}
@@ -0,0 +1,6 @@
prototypes:
standard:
formEditor:
dynamicJavaScriptModules:
additionalViewModelModules:
10: '@vendor/my-extension/backend/form-editor/view-model.js'
+320
View File
@@ -0,0 +1,320 @@
.. include:: /Includes.rst.txt
.. _apireference-frontendrendering:
============================
Building and rendering forms
============================
This chapter explains how EXT:form renders forms in the frontend and how
developers can build forms programmatically or customize the rendering
pipeline.
For the complete PHP API of every class mentioned here, see
`EXT:form API on api.typo3.org <https://api.typo3.org/main/namespaces/typo3-cms-form.html>`__.
.. contents::
:local:
:depth: 2
.. _apireference-frontendrendering-fluidformrenderer:
Template resolution (FluidFormRenderer)
========================================
The :php-short:`\TYPO3\CMS\Form\Domain\Renderer\FluidFormRenderer` resolves
Fluid templates, layouts and partials through rendering options defined in the
prototype configuration. All options are read from
:php-short:`\TYPO3\CMS\Form\Domain\Model\FormDefinition::getRenderingOptions()`.
.. _apireference-frontendrendering-fluidformrenderer-options:
.. _apireference-frontendrendering-fluidformrenderer-options-templaterootpaths:
templateRootPaths
-----------------
Defines one or more paths to Fluid **templates**.
Paths are searched in reverse order (bottom to top); the first match wins.
Only the root form element (type :yaml:`Form`) must be a **template** file.
All child elements are resolved as **partials**.
.. literalinclude:: _templateRootPaths.yaml
:caption: EXT:my_sitepackage/Configuration/Form/CustomPrototype.yaml
:language: yaml
With the default type :yaml:`Form` the renderer expects a file named
:file:`Form.html` inside the first matching path.
.. _apireference-frontendrendering-fluidformrenderer-options-layoutrootpaths:
layoutRootPaths
---------------
Defines one or more paths to Fluid **layouts**, searched in reverse order.
.. literalinclude:: _layoutRootPaths.yaml
:caption: EXT:my_sitepackage/Configuration/Form/CustomPrototype.yaml
:language: yaml
.. _apireference-frontendrendering-fluidformrenderer-options-partialrootpaths:
partialRootPaths
----------------
Defines one or more paths to Fluid **partials**, searched in reverse order.
Within these paths the renderer looks for a file named after the
form element type (e.g. :file:`Text.html` for a :yaml:`Text` element).
Use :ref:`templateName <apireference-frontendrendering-fluidformrenderer-options-templatename>`
to override this convention.
.. literalinclude:: _partialRootPaths.yaml
:caption: EXT:my_sitepackage/Configuration/Form/CustomPrototype.yaml
:language: yaml
.. _apireference-frontendrendering-fluidformrenderer-options-templatename:
templateName
------------
By default the element type is used as the partial file name
(e.g. type :yaml:`Text`:file:`Text.html`).
Set :yaml:`templateName` to use a different file instead:
.. literalinclude:: _templateName.yaml
:caption: EXT:my_sitepackage/Configuration/Form/CustomPrototype.yaml
:language: yaml
The element of type :yaml:`Foo` now renders using :file:`Text.html`.
.. _apireference-frontendrendering-renderviewHelper:
The render ViewHelper
=====================
.. _apireference-frontendrendering-renderviewHelper-arguments:
Use :html:`<formvh:render>` in a Fluid template to render a form.
The ViewHelper accepts the following arguments:
.. _apireference-frontendrendering-renderviewHelper-persistenceidentifier:
persistenceIdentifier
---------------------
Path to a YAML form definition. This is the most common way to render a
form:
.. literalinclude:: _renderPersistenceIdentifier.html
:caption: EXT:my_sitepackage/Resources/Private/Templates/ContactPage.html
:language: html
.. _apireference-frontendrendering-renderviewHelper-overrideconfiguration:
overrideConfiguration
---------------------
A configuration array that is merged **on top** of the loaded form
definition (or passed directly to the factory when no
:yaml:`persistenceIdentifier` is given).
This allows adjusting a form per usage without duplicating the YAML file.
.. _apireference-frontendrendering-renderviewHelper-factoryclass:
factoryClass
------------
A fully qualified class name implementing
:php-short:`\TYPO3\CMS\Form\Domain\Factory\FormFactoryInterface`.
Defaults to :php-short:`\TYPO3\CMS\Form\Domain\Factory\ArrayFormFactory`.
Set a custom factory to :ref:`build forms programmatically <apireference-frontendrendering-programmatically>`.
.. literalinclude:: _renderFactoryClass.html
:caption: EXT:my_sitepackage/Resources/Private/Templates/ContactPage.html
:language: html
.. _apireference-frontendrendering-renderviewHelper-prototypename:
prototypeName
-------------
Name of the prototype the factory should use (e.g. :yaml:`standard`).
If omitted the framework looks for the prototype name inside the form
definition; if none is found, :yaml:`standard` is used.
.. _apireference-frontendrendering-programmatically:
Building forms programmatically
===============================
Instead of writing YAML, you can create a form entirely in PHP by
implementing a custom :php:`FormFactory`.
.. rst-class:: bignums-xxl
1. Create a FormFactory
Extend :php:`AbstractFormFactory` and implement :php:`build()`.
Use :php:`FormDefinition::createPage()` to add pages,
:php:`Page::createElement()` to add elements, and
:php:`FormDefinition::createFinisher()` to attach finishers.
.. literalinclude:: _CustomFormFactory.php
:caption: EXT:my_sitepackage/Classes/Domain/Factory/CustomFormFactory.php
:language: php
2. Render the form
Reference your factory in a Fluid template:
.. literalinclude:: _renderFactoryClass.html
:caption: EXT:my_sitepackage/Resources/Private/Templates/ContactPage.html
:language: html
.. _apireference-frontendrendering-programmatically-key-concepts:
Key classes and their responsibilities
--------------------------------------
.. _apireference-frontendrendering-programmatically-apimethods-formruntime:
The following table lists the most important classes you work with when
building or manipulating forms programmatically. Use your IDE's
autocompletion or the
`API documentation <https://api.typo3.org/main/namespaces/typo3-cms-form.html>`__
for the full method reference.
.. list-table::
:header-rows: 1
:widths: 30 70
* - Class
- Purpose
* - :php-short:`\TYPO3\CMS\Form\Domain\Model\FormDefinition`
- The complete form model. Create pages (:php:`createPage()`),
attach finishers (:php:`createFinisher()`), look up elements
(:php:`getElementByIdentifier()`), and bind to a request
(:php:`bind()`).
* - :php-short:`\TYPO3\CMS\Form\Domain\Runtime\FormRuntime`
- A *bound* form instance (created by :php:`FormDefinition::bind()`).
Provides access to the current page, submitted values
(:php:`getElementValue()`), and the request/response objects.
This is the object available inside finishers and event listeners.
* - :php-short:`\TYPO3\CMS\Form\Domain\Model\FormElements\Page`
- One page of a multi-step form. Add elements with
:php:`createElement()`, reorder them with :php:`moveElementBefore()`
/ :php:`moveElementAfter()`.
* - :php-short:`\TYPO3\CMS\Form\Domain\Model\FormElements\Section`
- A grouping element inside a page. Same API as :php:`Page` for
managing child elements.
* - :php-short:`\TYPO3\CMS\Form\Domain\Model\FormElements\AbstractFormElement`
- Base class of all concrete elements. Most element types use
:php-short:`\TYPO3\CMS\Form\Domain\Model\FormElements\GenericFormElement`;
specialized subclasses include, e.g.
:php-short:`\TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload`.
Set properties (:php:`setProperty()`), add validators
(:php:`createValidator()`), define default values
(:php:`setDefaultValue()`).
* - :php-short:`\TYPO3\CMS\Form\Domain\Configuration\ConfigurationService`
- Reads the merged prototype configuration.
Call :php:`getPrototypeConfiguration('standard')` to obtain the
full array for a prototype.
.. _apireference-frontendrendering-programmatically-initializeformelement:
Initializing elements at runtime
---------------------------------
Override :php:`initializeFormElement()` in a custom form element class to
populate data (e.g. from a database) when the element is added to the form.
At that point the prototype defaults have already been applied; properties
from the YAML definition are applied **afterwards**.
.. tip::
If you only need to initialize an element without writing a full custom
class, listen to the :php:`BeforeRenderableIsAddedToFormEvent` PSR-14
event instead. See :ref:`apireference-events`.
.. _apireference-frontendrendering-finishers:
Working with finishers
======================
Custom finishers extend :php-short:`\TYPO3\CMS\Form\Domain\Finishers\AbstractFinisher`
and place their logic in :php:`executeInternal()`. The base class provides:
:php:`parseOption(string $optionName)`
Resolves a finisher option, applying form-element variable replacements
and TypoScript-style option overrides. Always prefer this over direct
array access.
The :php-short:`\TYPO3\CMS\Form\Domain\Finishers\FinisherContext` passed to
:php:`execute()` gives access to:
:php:`getFormRuntime()`
The :php-short:`\TYPO3\CMS\Form\Domain\Runtime\FormRuntime` for the current
submission.
:php:`getFormValues()`
All submitted values (after validation and property mapping).
:php:`getFinisherVariableProvider()`
A key/value store to **share data between finishers** within the same
request. The returned
:php-short:`\TYPO3\CMS\Form\Domain\Finishers\FinisherVariableProvider` offers:
:php:`add(string $finisherIdentifier, string $key, mixed $value)`
Store a value under a finisher-specific namespace.
:php:`get(string $finisherIdentifier, string $key, mixed $default = null)`
Retrieve a previously stored value (returns :php:`$default` if not set).
:php:`exists(string $finisherIdentifier, string $key)`
Check whether a value has been stored.
:php:`remove(string $finisherIdentifier, string $key)`
Remove a stored value.
:php:`cancel()`
Stops execution of any remaining finishers.
.. seealso::
:ref:`Accessing finisher options <concepts-finishers-customfinisherimplementations-accessingoptions>` |
:ref:`Sharing data between finishers <concepts-finishers-customfinisherimplementations-finishercontext-sharedatabetweenfinishers>`
.. _apireference-frontendrendering-runtimemanipulation:
Runtime manipulation
====================
.. _apireference-frontendrendering-runtimemanipulation-events:
EXT:form dispatches PSR-14 events at every important step of the rendering
lifecycle. Use them to modify the form, redirect page flow, or adjust
submitted values without subclassing framework internals.
.. seealso::
:ref:`PSR-14 events overview for EXT:form <apireference-events>`
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace Vendor\MySitePackage\Domain\Factory;
use Psr\Http\Message\ServerRequestInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Form\Domain\Configuration\ConfigurationService;
use TYPO3\CMS\Form\Domain\Factory\AbstractFormFactory;
use TYPO3\CMS\Form\Domain\Model\FormDefinition;
use TYPO3\CMS\Form\Domain\Model\FormElements\AbstractFormElement;
final class CustomFormFactory extends AbstractFormFactory
{
public function build(
array $configuration,
?string $prototypeName = null,
?ServerRequestInterface $request = null,
): FormDefinition {
$prototypeName ??= 'standard';
$configurationService = GeneralUtility::makeInstance(
ConfigurationService::class,
);
$prototypeConfiguration = $configurationService->getPrototypeConfiguration(
$prototypeName,
);
$form = GeneralUtility::makeInstance(
FormDefinition::class,
'ContactForm',
$prototypeConfiguration,
);
$form->setRenderingOption('controllerAction', 'index');
// Page 1 personal data
$page1 = $form->createPage('page1');
/** @var AbstractFormElement $name */
$name = $page1->createElement('name', 'Text');
$name->setLabel('Name');
$name->createValidator('NotEmpty');
/** @var AbstractFormElement $email */
$email = $page1->createElement('email', 'Text');
$email->setLabel('Email');
// Page 2 message
$page2 = $form->createPage('page2');
/** @var AbstractFormElement $message */
$message = $page2->createElement('message', 'Textarea');
$message->setLabel('Message');
$message->createValidator('StringLength', ['minimum' => 5, 'maximum' => 500]);
// Radio buttons
/** @var AbstractFormElement $subject */
$subject = $page2->createElement('subject', 'RadioButton');
$subject->setProperty('options', [
'general' => 'General inquiry',
'support' => 'Support request',
]);
$subject->setLabel('Subject');
// Finisher send email
$form->createFinisher('EmailToSender', [
'subject' => 'Contact form submission',
'recipients' => [
'info@example.com' => 'My Company',
],
'senderAddress' => 'noreply@example.com',
]);
$this->triggerFormBuildingFinished($form);
return $form;
}
}
@@ -0,0 +1,8 @@
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
layoutRootPaths:
10: 'EXT:form/Resources/Private/Frontend/Layouts/'
20: 'EXT:my_sitepackage/Resources/Private/Forms/Frontend/Layouts/'
@@ -0,0 +1,8 @@
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
partialRootPaths:
10: 'EXT:form/Resources/Private/Frontend/Partials/'
20: 'EXT:my_sitepackage/Resources/Private/Forms/Frontend/Partials/'
@@ -0,0 +1,3 @@
<formvh:render
factoryClass="Vendor\MySitePackage\Domain\Factory\CustomFormFactory"
/>
@@ -0,0 +1,3 @@
<formvh:render
persistenceIdentifier="EXT:my_sitepackage/Resources/Private/Forms/Contact.yaml"
/>
@@ -0,0 +1,6 @@
prototypes:
standard:
formElementsDefinition:
Foo:
renderingOptions:
templateName: 'Text'
@@ -0,0 +1,8 @@
prototypes:
standard:
formElementsDefinition:
Form:
renderingOptions:
templateRootPaths:
10: 'EXT:form/Resources/Private/Frontend/Templates/'
20: 'EXT:my_sitepackage/Resources/Private/Forms/Frontend/Templates/'
+20
View File
@@ -0,0 +1,20 @@
.. include:: /Includes.rst.txt
.. _apireference:
==============================
For Developers / API Reference
==============================
This chapter is a complete reference of the API of the form framework. It
mainly addresses your concerns as a developer.
.. toctree::
:maxdepth: 1
Events/Index
FormEditor/Index
FrontendRendering/Index
.. seealso::
All built-in finishers including their options and programmatic usage
is now described in: `Ready-to-use finishers <https://docs.typo3.org/permalink/typo3/cms-form:apireference-finisheroptions>`_.
+46
View File
@@ -0,0 +1,46 @@
.. include:: /Includes.rst.txt
.. _accessibility:
=============
Accessibility
=============
There are numerous accessibility rules when it comes to making a form accessible
to a large number of users. This includes accessibility to groups such as people
with a disability, the elderly, non-native speakers, etc.
The following should be kept in mind by editors creating forms
in the backend form editor:
Labels
======
Always use clear, descriptive labels in the :guilabel:`Label` field. Simply
putting the label in field :guilabel:`Placeholder` is not
considered accessible.
Descriptions
============
Add an extended description in the field :guilabel:`Description`.
Placeholder
===========
The :guilabel:`Placeholder` field should not contain the label.
It should contain example content to make filling out the field easier for
users.
Autocomplete
============
The autocomplete property should be used whenever a field contains personal
information. This property can then be used by assistive
technology to aid users to fill out forms. Select the desired purpose from the
select :guilabel:`Autocomplete`. See `Input Purposes for User Interface
Components at w3.org <https://www.w3.org/TR/WCAG21/#input-purposes>`__ for
an explanation of which purposes to use.
If additional input purposes are needed, your integrator or developer can
:ref:`add additional input purpose options <concepts-autocomplete-add-options>`.
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

+36
View File
@@ -0,0 +1,36 @@
.. include:: /Includes.rst.txt
.. _finishers:
.. _finishers-introduction:
.. _finishers-overview-of-finishers:
=========
Finishers
=========
Any number of "finishers" can be added to a form. Finishers are actions that will
be executed once the form has been submitted by a user.
In the following chapter, each finisher and its function will be explained. Not all
finishers can be added via the form editor. There are some
finishers that can only be added by integrators/ administrators. The following
finishers are available by default:
* :ref:`Email to sender (form submitter) <finishers-email-to-sender>`
* :ref:`Email to receiver (you) <finishers-email-to-receiver>`
* :ref:`Redirect to a page <finishers-redirect>`
* :ref:`Delete uploads <finishers-delete-uploads>`
* :ref:`Confirmation message <finishers-confirmation-message>`
.. figure:: Images/form_finishers_overview.png
:alt: Form editor - add new finishers.
Form editor - add new finishers
.. important::
Finishers are executed in the order that they appear in your form definition.
This is particularly important for the ``Redirect finisher``. Make sure
this finisher is the very last one to be executed. The ``Redirect finisher``
stops the execution of all subsequent finishers in order to perform the redirect.
Finishers defined after the ``Redirect finisher`` will be ignored.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 946 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1014 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 765 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 902 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 567 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 959 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

+651
View File
@@ -0,0 +1,651 @@
.. include:: /Includes.rst.txt
.. _form-elements:
==================================
Form elements and their properties
==================================
.. _form-elements-overview-of-form-elements:
Overview of form elements
-------------------------
.. figure:: Images/form_elements_all.png
:alt: Overview of all form elements included in the TYPO3 core. There may
be fewer or different elements in your installation.
Overview of all form elements included in TYPO3. There may be
fewer or different elements in your installation.
.. _form-elements-settings:
Form element settings
---------------------
Most form elements have these 7 basic settings:
- **Label**: Label of the element.
- **Description**: Description of the element. Can be used to
provide the user with more information about the expected input.
- **Placeholder**: Example of the expected content. Disappears with the user's
input.
- **Default value**: Preset value. Pre-entered by the system and does not
disappear with the user's input.
- **Mandatory field**: Specify whether the field is a mandatory field and thus
must be filled in by the user.
- **Custom error message**: Custom message that will be displayed to the user
if the field is not filled in. If you don't provide a message, a default
message is shown.
- **Validators**: Validators are used to check the data entered in the
field. The system displays error messages if there are errors.
.. warning::
If a form element is a required field or validators fail, error
messages are displayed by the browser. These error texts and formatting cannot be
changed by editors or integrators as they are controlled
by the browser/operating system.
.. _form-elements-basic-elements:
Basic form elements
-------------------
.. _form-elements-basic-elements-text:
Text
====
A single-line text field, e.g. for entering short information such as name,
address, location. This element has the
:ref:`basic settings <form-elements-settings>`.
.. figure:: Images/form_elements_text_1.png
:alt: Element 'Text' - preview in the frontend.
Element 'Text' - preview in the frontend.
.. figure:: Images/form_elements_text_2.png
:alt: Settings for the 'Text' element.
Settings for the 'Text' element.
.. _form-elements-basic-elements-textarea:
Textarea
========
A multi-line text field, e.g. for the free input of continuous text. This allows
the user to provide a short text such as a message. This element has the
:ref:`basic settings <form-elements-settings>`.
.. figure:: Images/form_elements_textarea_1.png
:alt: Element 'Textarea' - preview in the frontend.
Element 'Textarea' - preview in the frontend.
.. figure:: Images/form_elements_textarea_2.png
:alt: Settings for the 'Textarea' element.
Settings for the 'Textarea' element.
.. _form-elements-basic-elements-password:
Password
========
A single-line text field for entering a password. The browser "hides" the text
input, i.e. the entered characters are not visible. This element has the
:ref:`basic settings <form-elements-settings>`.
.. figure:: Images/form_elements_password_1.png
:alt: Element 'Password' - preview in the frontend.
Element 'Password' - preview in the frontend.
.. figure:: Images/form_elements_password_2.png
:alt: Settings for the 'Password' element.
Settings for the 'Password' element.
.. _form-elements-special-elements:
Special elements
================
Sometimes it is better to use special elements instead of simple text
elements. Mobile devices such as smartphones display on-screen keyboards. If you
use the "Email address" element the form field on the device will contain a
"@" character in a central position and a validator will be triggered
that checks for the input format "firstname.lastname@example.org".
.. _form-elements-special-elements-email:
Email address
==============
A single-line field for entering an email address. This element has the
:ref:`basic settings <form-elements-settings>`. In addition, the field has an
`Email` validator (this is the only validator available for this form element).
.. figure:: Images/form_elements_email_1.png
:alt: Element 'E-mail' - preview in the frontend.
Element 'E-mail' - preview in the frontend.
.. figure:: Images/form_elements_email_2.png
:alt: Settings for the 'E-mail' element.
Settings for the 'E-mail' element.
.. _form-elements-special-elements-telephone-number:
Telephone number
================
A single-line text field for entering a phone number. This element has the
:ref:`basic settings <form-elements-settings>`.
.. figure:: Images/form_elements_telephone_1.png
:alt: Element 'Telephone' - preview in the frontend.
Element 'Telephone' - preview in the frontend.
.. figure:: Images/form_elements_telephone_2.png
:alt: Settings for the 'Telephone' element.
Settings for the 'Telephone' element.
.. _form-elements-special-elements-url:
URL
===
A single-line text field for entering a URL. A URL is typically an internet
address, such as that of your website. This element has the
:ref:`basic settings <form-elements-settings>`
.. figure:: Images/form_elements_url_1.png
:alt: Element 'URL' - preview in the frontend.
Element 'URL' - preview in the frontend.
.. figure:: Images/form_elements_url_2.png
:alt: Settings for the 'URL' element.
Settings for the 'URL' element.
.. _form-elements-special-elements-number:
Number
======
A single-line text field for entering a number. A user can increase and decrease
the number in preconfigured steps using visual controls in the browser.
This element has the :ref:`basic settings <form-elements-settings>`.
By default, the field has a `Number` validator. Additional settings:
- **Step**: Here you can enter a number that defines the step size. The step size
is the amount by which a number is increased or decreased in the frontend.
.. figure:: Images/form_elements_number_1.png
:alt: Element 'Number' - preview in the frontend.
Element 'Number' - preview in the frontend.
.. figure:: Images/form_elements_number_2.png
:alt: Settings for the 'Number' element.
Settings for the 'Number' element.
.. _form-elements-special-elements-date:
Date
====
A single-line text field for entering a date.
`Most modern browsers <https://caniuse.com/input-datetime>`_ will also display a calendar from
which the user can select the date. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Frequency**: default value "1" means that the user can select every day.
.. figure:: Images/form_elements_date_1.png
:alt: Element 'Date' - preview in the frontend.
Element 'Date' - preview in the frontend.
.. figure:: Images/form_elements_date_2.png
:alt: Settings for the 'Date' element.
Settings for the 'Date' element.
.. _form-elements-select-elements:
Select elements
---------------
Select elements (including checkboxes, radio buttons and selectboxes) do not
allow a user to enter text. Instead, they offer a predefined
number of choices, for example, salutation options.
.. note::
Select elements behave differently to text fields if they are marked as
"required".Checkboxes with multiple choices, for example, cannot be
be required fields. This is not supported by the HTML standard.
.. _form-elements-select-elements-checkbox:
Checkbox
========
A simple checkbox. This element has the :ref:`basic settings <form-elements-settings>`.
.. figure:: Images/form_elements_checkbox_1.png
:alt: Element 'Checkbox' - preview in the frontend.
Element 'Checkbox' - preview in the frontend.
.. figure:: Images/form_elements_checkbox_2.png
:alt: Settings for the 'Checkbox' element.
Settings for the 'Checkbox' element.
.. _form-elements-select-elements-single-select:
Single selectbox
================
An element to create a drop-down list. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **First option**: Define the "empty option", i.e. the first element of the
selectbox. You can use this to provide additional guidance for the user.
- **Choices**: A tool to insert and manage options.
- **Label**: Name of the option.
- **Value**: Value of the option. The system automatically sets the
"Value" to the "Label". You can leave it like this if you are
unsure of what you are doing.
- **Selected**: Check this to pre-select an option in the frontend.
- **[ + ]**: Adds a new line for a new option.
.. figure:: Images/form_elements_singleSelect_1.png
:alt: Element 'Single select' - preview in the frontend.
Element 'Single select' - preview in the frontend.
.. figure:: Images/form_elements_singleSelect_2.png
:alt: Settings for the 'Single select' element.
Settings for the 'Single select' element.
.. _form-elements-select-elements-radiobutton:
Radio buttons
=============
An element to display one or more radio buttons. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Choices**: A tool to insert and manage the options.
- **Label**: Name of the option.
- **Value**: Value of the option. The system automatically sets the
"Value" to the "Label". You can leave it like this if you are
unsure of what you are doing.
- **Selected**: Check this to pre-select an option in the frontend.
- **[ + ]**: Adds a new line for a new option.
.. figure:: Images/form_elements_radioBtn_1.png
:alt: Element 'Radio button' - preview in the frontend.
Element 'Radio button' - preview in the frontend.
.. figure:: Images/form_elements_radioBtn_2.png
:alt: Settings for the 'Radio button' element.
Settings for the 'Radio button' element.
.. _form-elements-select-elements-multi-checkbox:
Multi checkbox
==============
An element to create one or more checkboxes. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Choices**: A tool to insert and manage the options.
- **Label**: Name of the option.
- **Value**: Value of the option. The system automatically sets the
"Value" to the "Label". You can leave it like this if you are
unsure of what you are doing.
- **Selected**: Check this to pre-select an option in the frontend.
- **[ + ]**: Adds a new line for a new option.
.. figure:: Images/form_elements_multiCheckbox_1.png
:alt: Element 'Multi checkbox' - preview in the frontend.
Element 'Multi checkbox' - preview in the frontend.
.. figure:: Images/form_elements_multiCheckbox_2.png
:alt: Settings for the 'Multi checkbox' element.
Settings for the 'Multi checkbox' element.
.. warning::
**HTML** does not check that "required" fields are filled out. They
are only checked after a form has been submitted.
.. _form-elements-select-elements-multi-select:
Multi select
============
An element to create a multiple selection. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **First option**: Define the "empty option", i.e. the first element of the
select. You can use this to provide additional guidance for the user.
- **Choices**: A tool to insert and manage the options.
- **Label**: Name of the option.
- **Value**: Value of the option. The system automatically sets the
"Value" to the "Label". You can leave it like this if you are
unsure of what you are doing.
- **Selected**: Check this to pre-select an option in the frontend.
- **[ + ]**: Adds a new line for a new option.
.. figure:: Images/form_elements_multiSelect_1.png
:alt: Element 'Multi select' - preview in the frontend.
Element 'Multi select' - preview in the frontend.
.. figure:: Images/form_elements_multiSelect_2.png
:alt: Settings for the 'Multi select' element.
Settings for the 'Multi select' element.
.. _form-elements-select-elements-country-select:
Country select
==============
An element to create a country selectbox. This element has the
:ref:`basic settings <form-elements-settings>` Additional settings:
- **First option**: Define the "empty option", i.e. the first element of the
select. You can use this to provide additional guidance for the user.
- **Prioritized countries**: A multi-selection of country names, which should
be listed as the top options in the form element.
- **Only countries**: Restrict the countries to be rendered in the selection.
- **Exclude countries**: Define which countries should not appear in the
selection.
.. _form-elements-advanced-elements:
Advanced elements
-----------------
.. _form-elements-advanced-elements-file-upload:
File upload
===========
An element to upload a file to the :guilabel:`File > Filelist` module. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Allowed Mime Types**: Select the allowed file extensions a user is able to
upload.
- **Storage path for uploads**: Select the storage path in your TYPO3 installation.
This is where the uploaded file will be saved.
.. figure:: Images/form_elements_fileUpload_1.png
:alt: Element 'File upload' - preview in the frontend.
Element 'File upload' - preview in the frontend.
.. figure:: Images/form_elements_fileUpload_2.png
:alt: Settings for the 'File upload' element.
Settings for the 'File upload' element.
.. error::
**Privacy issues**:
Keep in mind that the storage path you choose may not be protected. The path may
be indexed by your search and search engines. If you need to protect sensitive
documents, contact your administrator to create a secure storage path.
.. _form-elements-advanced-elements-hidden:
Hidden
======
A field that is not visible in the frontend. The form element is inside the red
rectangle in the image. Such a field might be needed for technical functionality,
e.g. to add hidden values to a form. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Value**: Here you can set a value for the element.
.. figure:: Images/form_elements_hidden_1.png
:alt: Element 'Hidden' - preview in the frontend.
Element 'Hidden' - preview in the frontend.
.. figure:: Images/form_elements_hidden_2.png
:alt: Settings for the 'Hidden' element.
Settings for the 'Hidden' element.
.. _form-elements-advanced-elements-image-upload:
Image upload
============
An element to upload an image to :guilabel:`File > Filelist`. This element has the
:ref:`basic settings <form-elements-settings>`. Other settings:
- **Allowed Mime Types**: Select the file extensions a user is allowed to
upload.
- **Storage path for uploads**: Select the storage path in your TYPO3 installation.
This is where the uploaded file will be saved.
.. figure:: Images/form_elements_imageUpload_1.png
:alt: Element 'Image upload' - preview in the frontend.
Element 'Image upload' - preview in the frontend.
.. figure:: Images/form_elements_imageUpload_2.png
:alt: Settings for the 'Image upload' element.
Settings for the 'Image upload' element.
.. error::
**Privacy issues**:
Keep in mind that the storage path you choose may not be protected. The path may
be indexed by your search and search engines. If you need to protect sensitive
documents, contact your administrator to create a secure storage path.
.. _form-elements-advanced-elements-advanced-password:
Advanced password
=================
The element is analogous to the `Password` form element. A single-line text
field is displayed for entering a password. The browser "hides" the text input,
i.e. the entered characters are not visible. Another field is displayed below it
so that the user has to repeat the password to prevent typing errors. This field
is useful for registration forms. This element has the
:ref:`basic settings <form-elements-settings>`. Additional settings:
- **Confirmation label**: Label for the confirmation field.
.. figure:: Images/form_elements_advancedPassword_1.png
:alt: Element 'Advanced password' - preview in the frontend.
Element 'Advanced password' - preview in the frontend.
.. figure:: Images/form_elements_advancedPassword_2.png
:alt: Settings for the 'Advanced password' element.
Settings for the 'Advanced password' element.
.. _form-elements-advanced-elements-static-text:
Static text
===========
A field for static text. This text cannot be formatted, which means you can't
insert links or highlight text. Instead, the text is output in the style of
your website. The settings for this element are:
- **Heading**: Heading for the element.
- **Text**: Content for the element.
.. figure:: Images/form_elements_staticText_1.png
:alt: Element 'Static text' - preview in the frontend.
Element 'Static text' - preview in the frontend.
.. figure:: Images/form_elements_staticText_2.png
:alt: Settings for the 'Static text' element.
Settings for the 'Static text' element.
.. _form-elements-advanced-elements-content-element:
Content element
================
You can display any content elements that are on your website. The settings for
this element are:
- **Content element uid**: ID of the content element you want to display. You can
either enter the ID manually or select it via the page tree.
To do this, click on the "Page content" button.
- **[ Page content ]**: Modal which displays the page tree. You can select
a page and the content element.
.. figure:: Images/form_elements_contentElement_1.png
:alt: Element 'Content element' - preview in the frontend.
Element 'Content element' - preview in the frontend.
.. figure:: Images/form_elements_contentElement_2.png
:alt: Settings for the 'Content element' element.
Settings for the 'Content element' element.
.. _form-elements-container-elements:
Container elements
------------------
Fieldset and grid elements are container elements that structure
your form in terms of content or visual appearance. Container elements can
be combined. For example, a fieldset can contain several grids.
.. _form-elements-container-elements-fieldset:
Fieldset
========
This container groups form elements based on content. This is
important for screen readers and helps you to improve the accessibility of your form.
For example, in an "Address" fieldset you could have
street, house number, postal code and city form elements. The settings for
this element are:
- **Field group name**: Heading for the field group, e.g. "Address".
.. figure:: Images/form_elements_fieldset_1.png
:alt: Element 'Fieldset' - preview in the frontend.
Element 'Fieldset' - preview in the frontend.
.. figure:: Images/form_elements_fieldset_2.png
:alt: Element 'Fieldset' - preview in the backend.
Element 'Fieldset' - preview in the backend.
.. figure:: Images/form_elements_fieldset_3.png
:alt: Settings for the 'Fieldset' element.
Settings for the 'Fieldset' element.
.. _form-elements-container-elements-grid:
Grid
====
Use this container element to place fields next to each other (create a visual structure).
**The additional settings apply to the content elements inside the grid**:
- **Configuration Grid Area**:
- Areas: **xs** (Very small), **sm** (Small), **md** (Medium), **lg** (Large),
**xl** (Extra large), **xxl** (Extra extra large).
- These are the "breakpoints". These are ranges of
resolutions or adaptations to different screen sizes. Smartphones,
for example, have a low resolution range (xs or sm) and desktop monitors
have a high resolution range (lg, xl or xxl). Use this to
abstractly control how many elements are displayed next to each other in
which resolution.
- **Number of columns for grid area "xx"**:
- Enter a number for the selected area.
- The number determines how much space the field takes up on the different
screen sizes and therefore how many elements are displayed next to
each other.
.. figure:: Images/form_elements_grid_1.png
:alt: Element 'Grid' - preview in the frontend.
Element 'Grid' - preview in the frontend.
.. figure:: Images/form_elements_grid_2.png
:alt: Element 'Grid' - preview in the backend.
Element 'Grid' - preview in the backend.
.. figure:: Images/form_elements_grid_3.png
:alt: Settings for the 'Grid' element - Part 1.
Settings for the 'Grid' element - Part 1.
.. figure:: Images/form_elements_grid_4.png
:alt: Settings for the 'Grid' element - Part 2.
Settings for the 'Grid' element - Part 2.
+61
View File
@@ -0,0 +1,61 @@
.. include:: /Includes.rst.txt
.. _forEditors:
===========
For Editors
===========
Introduction to forms
---------------------
Forms are provided by the **Form TYPO3 extension**. Form is a TYPO3 core
extension which has been available by default since TYPO3 version 8.
What can Form do?
-----------------
- TYPO3 core extension
- flexible, extensible and easy to use
- easy to use via drag-and-drop
- live preview
- form reuse
- create templates for new forms
- set mandatory fields
- set finishers (downstream processing)
- automatic spam protection
- multi-step forms
What can't Form do?
-------------------
Form has limited:
- formatting of form labels
- multilingual support
- possibilities for textual design of emails
When can I use Form?
--------------------
- for contact forms
- for application forms
- for simple or complex forms
- for different forms on my pages
Notes on data protection
------------------------
Data submitted in forms is not stored in the TYPO3 backend due to privacy reasons.
There are TYPO3 extensions that retrofit this behavior but we do not recommend using these
extensions. Instead, check if the form data can be transferred directly to your
CRM or similar tools.
.. toctree::
:maxdepth: 1
FormElements/Index
Validators/Index
Finishers/Index
Accessibility/Index
Tutorials/Index
Binary file not shown.

After

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Some files were not shown because too many files have changed in this diff Show More