The fields below are part of the node/add node/edit forms of my custom node type.
The paragraph field_para_city
contains multiple instances of field_city
.
field_city
has an allowed_values_function defined in the YML files, 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 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 clicks on anything in the paragraph, e.g. "Add city" or remove existing cities, then the entire paragraph is refreshed, and the options in all field_city
instances inside it 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 in order to get the correct cities again.
I found that although adding/removing a field_city
triggerred the above mentioned buildForm()
function, the $form_state->getValue('field_country')
was empty, unlike when buildForm()
is triggered through the field_country
AJAX.
I tried to capture the state of field_country
in the allowed_values_function 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?