Cannot get AJAX change to work

Created on 30 May 2025, 4 months ago

Problem/Motivation

I'm building a style option that updates as user selects options.

For instance, I have a select that when value 1 is picked, the next form element should be a set of radio buttons. For option 2 then a text area should be shown.

#ajax just has a change event that calls a public function that returns and AJAX response of commands (a single replace command with a css selector).

When I add the #ajax to the select element it triggers, but during the build set, I get an error if I try to get the values from form_state during the build configuration form step.

The subform and parent form must contain the #parents property, which must be an array

I did try to get the complete form state as it was mentioned in another issue reported, but the values don't include anything from the style options.

I would like to avoid manually traversing the posted data, but I'm not sure if I'm missing anything.

Proposed resolution

Have a way to access the posted data as part of the build configuration form step for AJAX requests.

💬 Support request
Status

Active

Version

1.1

Component

Code

Created by

🇨🇷Costa Rica alemadlei

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @alemadlei
  • 🇺🇸United States dobe

    This isn’t a “I didn’t namespace correctly” quirk—this behavior matches what others have described and strongly feels like a core/Form API/SubformState scoping/merging bug.

    What I observed:

    AJAX replacement works when you return the exact subtree (by slicing the real #parents chain).

    $form_state->setValue() does persist (values exist in the global state), but inside the plugin’s buildConfigurationForm() the subform cannot reliably getValue() its own updated values.

    The only way I could surface those values was via $form_state->set() (global state), and that breaks isolation when the same plugin is used multiple times (e.g., per-region)—unique instance IDs or manual namespacing didn’t fix it. That collision/visibility problem makes the intended per-subform instance set/get flow brittle or effectively broken.

    I tried the patches linked in https://www.drupal.org/project/drupal/issues/2798261 🐛 Using $form_state->getValue() in BlockBase's blockForm throws "subform and parent form must contain the #parents property" exception Needs work and they did not resolve what I’m seeing, so this is either the same underlying issue manifesting slightly differently or a closely related regression.

    Next logical step:
    Create a minimal reproducible case demonstrating:

    A subform (style option) with AJAX that sets a value,

    Rebuild and attempt to read that value in buildConfigurationForm(),

    Reuse the same plugin instance (e.g., per-region) to show the cross-instance collision when relying on the global workaround.

Production build 0.71.5 2024