In a hook, I use ajax on a form field, designed with drupal user interface. It is declared as this :

$form['field_unite_de_recherche']['widget']['#ajax'] = array(
'callback' => 'ajax_equipes_from_unites_callback',
'event' => 'change',
'method' => 'replace',
'wrapper' => 'edit-field-equipe-membre2',

In the callback function, I retreive some values in the database from the selected value in field_unite_de_recherche :

$selected = $form_state->getValue('field_unite_de_recherche');
$query = \Drupal::database()->select(...);
$result = $query->execute();
while ($row = $result->fetchAssoc()) {
 $options[] = $row['title'];

Then, in this callback function, I build the new version of the widget :

$form['field_equipe_membre2'] = [
'#type' => 'select',
'#title' => 'Equipe membre2',
'#options' => $options,
return $form['field_equipe_membre2'];

The first time I select a value in the "field_unite_de_recherche" field, the field "field_equipe_membre2" is rebuild with the right values from the database.

With a new selection in "field_unite_de_recherche" field, the values are well retrieved from the database, but the "field_equipe_membre2" field is not updated with the new values.

I am sure that the values are well retrieved from this second selection because I write them in a file as in the following

$handle = fopen('debug.txt','w');
while ($row = $result->fetchAssoc()) {
  $options[] = $row['title'];
  fputs($handle, $row['title']."\n");

The question is : why the "field_equipe_membre2" is rebuild only the first time?

I red a number of messages on this forum :

  • A "rebuild" command is not required because it is "included" in a ajax command
  • there is no cache for ajax

I also look at ajax examples module, but they do not concern hook manner

Can someone give me an advice?

Additionnaly, even with

'method' => 'replace',

in ajax declaration, I did not succeeded to avoid the creation of a new "field_equipe_membre2" field in the form. I tried to return


without any success. How to do to replace the existing one, not create a new one?

  • I solved the two problems. To replace the existing widget (i.e. : to avoid the creation of a new one) : use the id of the div of the widget, not the id of the widget itself. To replace the option array : choose "html" as method instead of "replace".
    – cocq
    Jun 17 '21 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.