Regression on entity reference field states

Created on 23 January 2024, 5 months ago
Updated 9 February 2024, 5 months ago

Problem/Motivation

I have added field conditions in my project using states. I have textfields that are depending on entity reference fields being filled before the textfields are shown. After changes done in issue https://www.drupal.org/project/drupal/issues/3347144 🐛 Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) Needs work these field conditions do not work anymore. When entity reference field value is filled, the visible state is not anymore triggered on the dependent field.

Steps to reproduce

Create a content type and add there a text field and an entity reference field (mine is used to reference Media).

Create a custom module and in the .module file, add a visible state to a textfield with field_widget_single_element_form_alter -hook. In this case the textfield machine name is 'field_image_caption_short' and the entity referend field is 'field_main_media'.

function test_conditional_fields_field_widget_single_element_form_alter(&$element, &$form_state, $context): void {

  $field_definition = $context['items']->getFieldDefinition();
  $field_name = $field_definition->getName();

  if ($field_name !== 'field_image_caption_short') {
    return;
  }

  // Create a selector for the "depended_field" field.
  $fieldSelector = sprintf(':input[name="%s[%s]"]', 'field_main_media', 'target_id');

  // Alter the widget state.
  $element['value']['#states'] = [
    'visible' => [
      $fieldSelector => ['filled' => TRUE],
    ],
  ];
}

I have checked that the element names are still correct so the state change should work. State change also works when having the textfield be dependent on another textfield.

🐛 Bug report
Status

Fixed

Version

10.2

Component
Javascript 

Last updated about 7 hours ago

Created by

🇫🇮Finland thatguy

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

Comments & Activities

  • Issue created by @thatguy
  • 🇺🇸United States cilefen

    Are there console errors? Be sure to test with the 10.2.x branch as there are JavaScript fixes on it.

  • 🇫🇮Finland thatguy

    There are no console errors and I have tested this with a clean 10.2.3-dev setup as well and the issue is present there too

  • 🇺🇦Ukraine Stockticker

    +1. In my case, it's:

    $form["submit"]['#states'] = [
            'disabled' => [
              ':input[name="file_upload[fids]"]' => ['empty' => TRUE],
            ],
          ];

    it stopped working after upgrading to 10.2.2.

  • 🇺🇸United States hablat

    We're running into this issue ourselves.

    Narrowed it down to the following line in core/misc/states.js changing from
    const $states = $(context).find('[data-drupal-states]');
    to
    const elements = once('states', '[data-drupal-states]', context);
    due to the the fix in
    https://www.drupal.org/project/drupal/issues/3347144 🐛 Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) Needs work

    We have a temporary fix at the moment with a custom patch that changes
    const elements = once('states', '[data-drupal-states]', context);
    back to
    const elements = $(context).find('[data-drupal-states]');

    We're using this until someone comes up with a better patch.

  • 🇺🇸United States lpeabody

    This is one of those things where it would be nice for Drupal core maintainers to come up with JS contracts similar to the way they have developed Interface contracts for swappable Symfony services and public data members and functions.

    We ran into a similar issue where we are dependent on Facets checkbox list selections to determine state of a form element on the page. The state logic lives on the form element, so every time Facets re-creates its blocks via AJAX we need to rerun the States API behaviors on the form element. This stopped working after the previously mentioned Core update to the States API.

    Before

    1. Page loads.
    2. Form button is default disabled (becomes enabled if one of three Facets checkbox list blocks contains any checked elements).
    3. Facets blocks initially loaded with list of links (Facets later transforms these to checkboxes in custom JavaScript https://git.drupalcode.org/project/facets/-/blob/2.0.x/js/checkbox-widge...).
    4. Facet behavior checkbox JS runs and converts links into checkboxes for each checkbox widget block on page. Part off this behavior invokes Drupal.attachBehaviors for each instance of the converted Facet block, passing the Facets checkbox list block as the context, along with Drupal.settings.
    5. In our custom JS, we have a behavior whose attach function looks at the context and determines if it was a facet checkbox list, and if it is then it re-runs Drupal.attachBehaviors() to ensure that the States API re-applies state information on the form element who has these checkbox value depenencies.

    Workaround to account for new once usage in States API

    Our workaround was to remove the added once attribute on the pertinent form element, which might be how this needs to be handled going forward.

    1. Page loads.
    2. Form button is default disabled (becomes enabled if one of three Facets checkbox list blocks contains any checked elements).
    3. Facets blocks initially loaded with list of links (Facets later transforms these to checkboxes in custom JavaScript https://git.drupalcode.org/project/facets/-/blob/2.0.x/js/checkbox-widge...).
    4. Facet behavior checkbox JS runs and converts links into checkboxes for each checkbox widget block on page. Part off this behavior invokes Drupal.attachBehaviors for each instance of the converted Facet block, passing the Facets checkbox list block as the context, along with Drupal.settings.
    5. In our custom JS, we have a behavior whose attach function looks at the context and determines if it was a facet checkbox list, and if it is then it first removes the data-once value that was added to the form element, then it re-runs Drupal.attachBehaviors() to ensure that the States API re-applies state information on the form element who has these checkbox value dependencies.

    I couldn't find a better, documented way to handle this situation. I feel at the very least the bugfix issue ( https://www.drupal.org/project/drupal/issues/3347144 🐛 Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) Needs work ) could use a change record to indicate what changed and why it changed, and perhaps also document workarounds to account for the changes given the use-cases presented in this issue.

  • 🇺🇸United States attheshow

    +1 for patch in #5.

    Our form states were broken as well after upgrading to 10.2.2 today.

  • Status changed to Fixed 5 months ago
  • 🇬🇧United Kingdom catch

    Thanks for the reports. I've reverted 🐛 Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) Needs work and re-opened that issue, closing this issue as fixed - we can continue on the bug found here over there. The revert will be included in the next 10.2.x patch release.

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.69.0 2024