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 a YML file, 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?