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 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.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | 3416398-12-reference-field-states.patch | 555 bytes | alexander tallqvist |
| #5 | 3416398-1.patch | 444 bytes | hablat |
Issue fork drupal-3416398
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
cilefen commentedAre there console errors? Be sure to test with the 10.2.x branch as there are JavaScript fixes on it.
Comment #3
thatguy commentedThere 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
Comment #4
stockticker commented+1. In my case, it's:
it stopped working after upgrading to 10.2.2.
Comment #5
hablat commentedWe'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
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.
Comment #6
lpeabody commentedThis 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) 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.
Comment #7
attheshow commented+1 for patch in #5.
Our form states were broken as well after upgrading to 10.2.2 today.
Comment #8
catchI've re-opened #3347144: Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) to potentially roll it back.
Comment #9
catchThanks for the reports. I've reverted #3347144: Form API #states property/states should use .once() to apply its rules (Can cause failures with BigPipe and possibly other situations) 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.
Comment #12
alexander tallqvist commentedStill experiencing the same problem @thatguy described when running Drupal 10.3.2. The patch provided in #5 seems to fix the issue. Re-rolling the same patch for 10.3.2.
Comment #13
nod_a proper fix is in the works for core, could you test #3468860: JS #states behavior does not have a detach method. It should fix this but introduces another change in that #states about a missing element are now applied, they used to be ignored.