---
title: "Deprecation: #91787 - Inline JavaScript in fieldChangeFunc"
manual: "TYPO3 Core Changelog"
version: "main"
permalink: "https://docs.typo3.org/permalink/changelog:deprecation-91787"
source: "Changelog/11.5/Deprecation-91787-DeprecateInlineJavaScriptInFieldChangeFunc.rst"
modified: "2026-09-14T09:47:36+00:00"
---

# Deprecation: #91787 - Inline JavaScript in fieldChangeFunc

See [forge#91787](https://forge.typo3.org/issues/91787)

## Description

Custom `FormEngine` nodes allow to use internal property `fieldChangeFunc`
to add or modify client-side JavaScript behavior when field values are changed.

In the past these declarations basically were inline JavaScript, provided in
PHP and forwarded to the browser via HTML `onchange` or `onclick`
event attributes. In favor of introducing content security policy headers and
to reduce inline JavaScript, those functionality shall be defined in a
structured way & custom client-side behavior shall be provided by corresponding
JavaScript modules instead.

As a result, `fieldChangeFunc` declarations are not using plain inline
JavaScript (as scalar `string`) anymore, but make use of corresponding objects
implementing new `\TYPO3\CMS\Backend\Form\Behavior\OnFieldChangeInterface`.
This interface provides both a new structured and declarative approach via
`JSON` \- but also allows to fallback to legacy inline JavaScript in case it
is required in combination with legacy 3rd party extensions.

Using `fieldChangeFunc` with scalar `string` values has been marked as deprecated and has to
be substituted with specific implementations of `OnFieldChangeInterface`.

## Impact

Using `fieldChangeFunc` with scalar `string` values will trigger a
PHP `E_USER_DEPRECATED` error.

## Affected Installations

Installations implementing custom `FormEngine` components (wizards, nodes,
render-types, ...) that provide inline JavaScript using `fieldChangeFunc`.

```php
// examples
$this->data['parameterArray']['fieldChangeFunc']['example'] = "alert('demo');";
$parameterArray['fieldChangeFunc']['example'] = "alert('demo');";
```

## Migration

The following steps provide a brief overview of the new components in order to
avoid inline JavaScript. A complete and installable example is available with
[ext:demo_91787](https://github.com/ohader/demo_91787).

### PHP `OnFieldChangeInterface` instance

```php
<?php
namespace TYPO3\Example;

use TYPO3\CMS\Backend\Form\Behavior\OnFieldChangeInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class AlertOnFieldChange implements OnFieldChangeInterface
{
    protected string $value = 'demo';
    public function __toString(): string
    {
        // provides `alert('demo')` as plain inline JavaScript
        return sprintf(
            'alert(%s)',
            // always make sure to encode data, mitigating XSS
            GeneralUtility::quoteJSvalue($this->value)
        );
    }
    public function toArray(): array
    {
        // provides structured representation
        return [
            // handler `name` as registered with `FormEngine.js`
            'name' => 'example-alert',
            // fixed `data` segment
            'data' => [
                // ... can contain any arbitrary & custom payload
                'value' => $this->value,
            ]
        ];
    }
}
```

### PHP `FormEngine` consumer

```php
<?php
namespace TYPO3\Example;

use TYPO3\CMS\Backend\Form\Element\InputTextElement;
use TYPO3\CMS\Core\Page\PageRenderer;
use TYPO3\CMS\Core\Utility\GeneralUtility;

// just extending `input` TCA render-type, to keep it simple
class ConsumingElement extends InputTextElement
{
    public function render()
    {
        // uses custom `OnFieldChangeInterface` implementation from above
        // (whenever the value of this field is changed, an alert message shall be shown)
        $this->data['parameterArray']['fieldChangeFunc']['example'] = new AlertOnFieldChange();
        // side-note: before having `OnFieldChangeInterface`, it looked like this using inline code
        // $this->data['parameterArray']['fieldChangeFunc']['example'] = "alert('demo');";

        $pageRenderer = GeneralUtility::makeInstance(PageRenderer::class);
        // registers RequireJS module to register & handle that `fieldChangeFunc` instruction
        // (JavaScript module is loaded from `ext:example/Resources/Public/JavaScript/Demo.js`)
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Example/Demo');

        // just use parent method to render that `<input type="text">` field
        return parent::render();
    }
}
```

### JavaScript `FormEngine` registration

JavaScript module `TYPO3/CMS/Example/Demo` is fetched via RequireJS from
resource path `ext:example/Resources/Public/JavaScript/Demo.js`.

```javascript
define(['TYPO3/CMS/Backend/FormEngine'], (FormEngine) => {
    FormEngine.registerOnFieldChangeHandler(
        // `example-alert` as defined in `name` segment from PHP `AlertOnFieldChange::toArray()`
        'example-alert',
        // `data` segment from PHP `AlertOnFieldChange::toArray()`
        (data) => { alert(data.title); }
    );
})
```
