Problem/Motivation
Form API's States js behavior is initialized twice when BigPipe is enabled (and it is enabled by default), that causes misbehaviors when a user loads a form with already filled data from the server.
Steps to reproduce
Option 1: How it was initially discovered:
- ensure the BigPipe module is installed
- install webform
- create a form using:
first:
'#type': likert
'#title': First
'#questions':
Q1: Q1
Q2: Q2
Q3: Q3
'#answers':
A1: A1
A2: A2
A3: A3
container:
'#type': container
'#states':
visible:
- ':input[name="first[Q1]"]':
value: A3
- or
- ':input[name="first[Q2]"]':
value: A3
- or
- ':input[name="first[Q3]"]':
value: A3
markup:
'#type': markup
'#markup': '<p>Second Question text</p>'
q1:
'#type': radios
'#title': Q1
'#options':
A: A
B: B
C: C
q2:
'#type': radios
'#title': Q2
'#options':
A: A
B: B
C: C
q3:
'#type': radios
'#title': Q3
'#options':
A: A
B: B
C: C
- go to the webform test tab
- refresh until first table has 2 A3 selected (right most column)
- change the A3 -> A2 answer for one of the questions
- expected: second section should still be visible
- actual: second section is hidden
Option 2: Using webtools to see that state.Dependent are initialized twice
- ensure the BigPipe module is installed
- in core/misc/states.js
- add debugger / log statement for the initialization of a states.Dependent
- expected: initialized once
- actual: initialized twice
Proposed resolution
- rewrite the behavior attach function using the the once helper as in:
Drupal.behaviors.states = {
attach(context, settings) {
once('drupal-states-init', '[data-drupal-states]', context)
.forEach(function (element) {
const $element = $(element);
const config = JSON.parse(
element.getAttribute('data-drupal-states'),
);
Object.keys(config || {}).forEach((state) => {
new states.Dependent({
element: $element,
state: states.State.sanitize(state),
constraints: config[state],
});
});
});
// Execute all postponed functions now.
while (states.postponed.length) {
states.postponed.shift()();
}
},
};
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet