The fields below are part of the node/add node/edit forms of my custom node type.
The paragraph field_para_city
contain one field_city
. (I later need to add other fields in the paragraph).
The user can add multiple instances from field_para_city
.
field_city
has an allowed_values_function defined in thea YML filesfile, which returns all possible cities from all countries.
I created a class MyNodeTypeForm extends NodeForm
, with a public function buildForm()
. This function adds AJAX to field_country
so that when it changes (i.e. the user chooses a country) it (re-)populates all the existing instances of field_city (inside the field_para_city
instances) with corresponding list of cities (e.g., London and Cardiff for the UK).
In MY_MODULE.module, I added the following so that the above code is executed on the node/add and node/edit forms.
function MY_MODULE_entity_type_alter(array &$entity_types) {
$handlers = $entity_types['node']->get('handlers');
$handlers['form']['default'] = 'Drupal\MY_MODULE\Form\MyNodeTypeForm';
$handlers['form']['edit'] = 'Drupal\MY_MODULE\Form\MyNodeTypeForm';
$entity_types['node']->set('handlers', $handlers);
}
All works fine, except when the user add or remove instances of field_para_city
("Add city" or "Remove"), then all instances of the field_para_city
are refreshed and field_city
instances inside them are reset to the allowed values (all cities), ignoring the state of field_country
.
The user would then need to re-select from field_country
to get the correct cities again.
I found that although adding/removing a field_para_city
triggered the above mentioned buildForm()
function, the $form_state->getValue('field_country')
was then empty, unlike when buildForm()
is triggered through the field_country
AJAX.
I tried to capture the state of field_country
in the field_city
's allowed_values_function, so that the allowed options are dynamically and directly set based on the user choice of country, but $form_state
was not recognised there.
I know this is an incorrect approach!
What is the correct better approach to implement this simple use case?