TYPO3 v15 dev-main snapshot ()
This commit is contained in:
@@ -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');
|
||||
}
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
+18
@@ -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') ?? '';
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
+11
@@ -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'
|
||||
Reference in New Issue
Block a user