Score:0

rebuild a form with ajax (solved)

gb flag

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");
}
fclose($handle);

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

$form['field_equipe_membre2']['#options']

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

cocq avatar
gb flag
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".
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.