Problem/Motivation
With #3294720: The attachBehaviors() for document is only called after Big Pipe chunks are processed the Drupal Behaviors are being applied for entire page twice.
This causes, that states' rules are initiated multiple times and this causes that states sometimes works unexpected if BigPipe is available.
Steps to reproduce
Create a form containing complex states logic:
$form['option'] = [
'#type' => 'radios',
'#title' => 'Option',
'#options' => [
'option_1' => 'option_1',
'option_2' => 'option_2',
],
'#default_value' => 'option_1',
'#required' => TRUE,
];
$form['variant'] = [
'#tree' => TRUE,
];
$form['variant']['option_1'] = [
'#type' => 'radios',
'#title' => 'Variant for option_1',
'#options' => [
'variant_1' => 'variant_1',
'variant_2' => 'variant_2',
],
'#default_value' => 'variant_1',
'#required' => TRUE,
'#states' => [
'visible' => [
':input[name="option"]' => ['value' => 'option_1'],
],
],
];
$form['variant']['option_2'] = [
'#type' => 'radios',
'#title' => 'Variant for option_2',
'#options' => [
'variant_1' => 'variant_1',
'variant_2' => 'variant_2',
],
'#default_value' => 'variant_1',
'#required' => TRUE,
'#states' => [
'visible' => [
':input[name="option"]' => ['value' => 'option_2'],
],
],
];
foreach($form['option']['#options'] as $option_key => $option_title) {
foreach($form['variant'][$option_key]['#options'] as $variant_key => $variant_title) {
$key = $option_key . '__' . $variant_key;
$form['info'][$key] = [
'#type' => 'container',
'#states' => [
'visible' => [
':input[name="option"]' => ['value' => $option_key],
':input[name="variant[' . $option_key . ']"]' => ['value' => $variant_key],
],
],
'text' => [
'#markup' => 'info for option ' . $option_title . ' variant ' . $variant_title,
],
];
}
}
And for visitor with BigPipe enabled (f.e logged in) the first click on any radio button will lead that text line will not be visible at all.
Other clicks on any radio will work as expected.
Proposed resolution
Use `once` to select element with defined states to apply them.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|
Issue fork drupal-3347144
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
Evaldas UžkurasComment #3
Evaldas UžkurasHere's a patch adding use of `once` as I proposed.
Comment #4
rodrigoaguileraThank you for creating the issue and providing a patch.
Bugs should be fixed in the latest dev version of Drupal and then backported to older versions like 9.5.x when applicable.
Since D10 doesn't use es6.js files anymore the patch needs to be different for D10.
Also we should provide one of this scenarios as a js test to be able ensure the behaviour stays consistent in the future
Comment #6
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedI can confirm this issue atleast in 9.5 and 9.2, the patch at #3 resolves it for me, atleast in my situation BigPipe is not used when anonymous/not-logged-in, but on logged in, bigpipe is activated and then I get missing form states, btw @evaldas-užkuras thanks!!
Comment #7
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedComment #9
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedThere is this one which is sort of related https://www.drupal.org/project/drupal/issues/3337995 but was closed
Comment #10
abrammI'm a bit surprised that
#states
wasn't usingonce()
, it's even declared as dependency to thedrupal.states
library.This is definitely a bug which affects BigPipe and AJAX use cases. The patch looks correct (didn't test it though).
Comment #11
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedComment #12
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedJust throwing this out there, maybe `states` doesnt bind with the right 'context' ? https://www.drupal.org/project/drupal/issues/3337995#comment-15060748
Comment #13
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedComment #14
dgtlmoon CreditAttribution: dgtlmoon as a volunteer commentedComment #15
smustgrave CreditAttribution: smustgrave at Mobomo commentedDid not test.
But was previously tagged for tests which still need to happen. May be worth posting in #testing channel for suggestions where to add.
Comment #16
bkosborneThis was a tricky one to debug, but doing so eventually led to me here today. Here's an example form that is affected by this bug which I think can be used as basis for a regression test of the fix:
In this example, if the select box has the first option selected AND the checkbox is checked, the textfield should be shown. However, on page load w/ Big Pipe enabled, checking the checkbox (which meets conditions) does NOT show the textfield. You have to uncheck and then recheck it before it finally works.
Big Pipe causes two more invocations of Drupal behaviors, resulting in a total of 3 invocations with the form items in the context. That's enough to cause issues with the logic with the 3 duplicate states behaviors defined.
Comment #17
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedI just closed #3383972: States JavaScript should use the once library, causes problems with Big Pipe as a duplicate of this issue. There is some information on how to reproduce with the contributed Webform module in the IS of that issue and MR with a similar but slightly different approach to fixing this.
Comment #19
mstrelan CreditAttribution: mstrelan at PreviousNext for Service NSW commentedEnabled
big_pipe
module on existingJavascriptStatesTest
. Test-only job should show it failing.Comment #20
mstrelan CreditAttribution: mstrelan at PreviousNext for Service NSW commentedWell GitLab CI made a liar out of me. For some reason it decided to skip the test instead of running it and letting it fail. Attaching a patch to see what Drupal CI thinks.
FWIW this is the result when running the test-only changes locally:
Comment #21
smustgrave CreditAttribution: smustgrave at Mobomo commentedHiding #20 so bot doesn't pick it up.
Going to post in gitlab channel but I see this test-only job failed correctly https://git.drupalcode.org/issue/drupal-3347144/-/jobs/471592
But change seems good, had to look up the param changes but looks good.
Comment #22
quietone CreditAttribution: quietone at PreviousNext commentedI'm triaging RTBC issues. I read the IS and the comments. I didn't find any unanswered questions or other work to do.
Leaving at RTBC.
Comment #24
catchCommitted/pushed to 11.x and cherry-picked to 10.2.x, thanks!
Comment #27
catchComment #29
attheshow CreditAttribution: attheshow at Richland Library commentedRelated regression ticket is here: https://www.drupal.org/project/drupal/issues/3416398
Comment #30
catchThe regression in #3416398: Regression on entity reference field states seems like it might be worse than the bug with big pipe that this fixed - I'm considering rolling this back in 11.x and 10.2.x, so we can try again.
Comment #31
bkosborneHmm, tricky. So it seems the problem is that states sometimes needs to be applied again because the dependents may have changed, right?
In that case, I guess we need a way for states behavior to replace the existing state that was there before so it doesn't create duplicate state definitions.
Comment #34
catchDiscussed this briefly with nod_ in slack and we both think reverting is probably the best approach here - more sites are still on 10.1.x than 10.2.x, so reverting the bug fixed here won't be a regression for them, but the regression introduced with be a new bug when those sites update. Also doesn't seem like there's an easy fix for this in either direction, we probably can't use once, and might need to make the states javascript re-entrant instead, no idea what that means in practice.
Comment #36
acbramley CreditAttribution: acbramley at PreviousNext commentedRerolling and marking as needs tests to cover the bug found in #3416398: Regression on entity reference field states
Comment #37
sukr_s CreditAttribution: sukr_s as a volunteer commentedThis issue is a duplicate of #3386191: #states not working correctly when built from a logical combination of multliple fields