eca_form: "Form field: set as disabled" not working well for textarea widgets
Problem/Motivation
Flagging actions like "Form field: set as disabled" are currently having a complex problem with textarea widgets. Other types of widgets may be affected as well from this, as the mechanic is not bound to textarea widgets only. However it can be easily reproduced with that type of widget.
Basically with this problem, it's hard to disable textarea widgets using formatted text.
Steps to reproduce
Example:
Every new node type gets a body field. This field is a formatted text with summary field, and it's using a textarea widget for being displayed in a form.
Now try to create an ECA config that reacts upon "Process form" and then use "Form field: set as disabled" to disable the body value. A valid form field name would be "body.0.value". Same for the format body.0.format. Unfortunately this doesn't work for both. Interestingly though, it works for body.0.summary when the summary input is enabled.
Proposed resolution
There is no solution path yet for this problem, but the cause is known:
Textarea widgets are building up a render array using $element['#type'] = 'text_format'; as can be found in Drupal\text\Plugin\Field\FieldWidget\TextareaWidget. That render array will then be build up with its own process callback:
Drupal\filter\Element\TextFormat will add
return [
'#process' => [
[$class, 'processFormat'],
],
'#base_type' => 'textarea',
'#theme_wrappers' => ['text_format_wrapper'],
];
The form builder service will call all process callback from top to bottom. ECA will be fired up at the top, while the specified process callback of the textarea widget will be called later on as it is a child element of the form. There is currently no mechanic known where ECA could hook into afterwards. There is "After build form" event, but that one is way too late.
I was thinking about adding a process callback right into the element widget, but then I don't know what to do with it. Even worse, the validate callback of the flagging action won't find the targeted element, as it's not yet build up.