Bonjour,
Cela fait maintenant une semaine que j'essaie vainement de comprendre le fonctionnement des formulaires de Drupal. Je précise que je suis loin d'être un spécialiste d'Ajax, je ne connais que moyennement le DOM et je débute avec Drupal.
J'évolue sous Drupal 8.6.3, et je développe avec Netbeans configuré pour l'occasion depuis chez moi, sachant que mon Drupal se trouve sur un serveur Linux Ubuntu 18.04 LTS hébergé chez OVH.
J'essaie de créer un module de gestion de stock pour mon boulot. C'est pourquoi en ce moment je travailles sur un formulaire de saisie d'inventaire.
Ce dernier est constitué de plusieurs champs texte, de deux listes déroulantes contenant des choix, et de deux boutons. Un pour enregistrer la saisie, l'autre pour l'annuler.
Voilà à quoi ressemble ce formulaire :
Vous remarquerez que j'ai surligné trois champs dans ce cliché. Les champs "Type ou modèle :", "N° de série :" et "Description :". J'ai surligné ces champs parce qu'en fait, ces trois informations sur le matériel inventorié sont déjà connues et se trouvent dans une base de données. Le but de cet inventaire est de les compléter d'une géolocalisation du matériel, d'où les autres champs qui eux sont à renseigner manuellement.
Dans son fonctionnement, après avoir saisi la référence dans le premier champs texte, l'utilisateur va naturellement dérouler la liste de sélection d'agence, puis celle des étages. À ce moment précis, le champ texte de la référence perd le focus ce qui a pour résultat d'un point de vue Ajax de lever l'événement 'change' pour le champ texte "Référence :". Mon code exploite cet événement pour réagir à ce moment et prend alors en charge la récupération des trois informations citées ci-dessus en vue de les placer dans les champs texte concernés :
Cette première mécanique fonctionne très bien dans le sens où lorsque je saisi la référence et que je faits perdre le focus au champ texte, la fonction AjaxCallback est bien appelée. Voilà ce qu'elle fait :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 $form['txt_reference'] = [ '#type' => 'textfield', '#title' => $this->t('Référence (-------):'), '#required' => true, '#ajax' => [ 'callback' => [$this, 'AjaxTraiteReference'], 'event' => 'change', 'progress' => [ 'type' => 'throbber', 'message' => t('Vérification de la référence...'), ], ], '#prefix' => '<span id="error-message-txt_reference"></span>', ];
Voilà le code de définition de ces trois champs texte dédiés aux valeurs connues :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 public function AjaxTraiteReference(array &$form, FormStateInterface $form_state): AjaxResponse { $response = new AjaxResponse(); $nomcible = $form_state->getTriggeringElement()['#name']; \Drupal\Core\Database\Database::setActiveConnection('stock'); $database = \Drupal\Core\Database\Database::getConnection('stock'); $verif = $database->select('materielorigine', 'mat') ->condition('mat.reference', $form_state->getValue('txt_reference', '#value'), '=') ->fields('mat', ['type', 'numserie', 'description'])->execute()->fetchAssoc(); $rep = $verif['type']; $num = $verif['numserie']; $des = $verif['description']; $verif = $database->select('Inventaire', 'Inventaire') ->condition('Inventaire.reference', $form_state->getValue('txt_reference', '#value'), '=') ->fields('Inventaire', ['reference'])->execute()->fetchAssoc(); $ctrl = $verif['reference']; $message = (!empty($ctrl)) ? $this->t('<P><B><I> ' . $ctrl . ' a déjà été inventorié !</B></I></P>') : $this->t('<P><B><I>Matériel inconnu ?!</B></I></P>'); $css = ['border' => '2px solid red']; if ((!empty($rep) || !empty($num) || !empty($des)) && empty($ctrl)) { $css = ['border' => '2px solid green']; $message = $this->t('<P><B><I>Matériel connu non inventorié.</I></B></P>'); $elem = [ '#type' => 'textfield', '#title' => '', '#size' => '20', '#value' => $rep, '#attributes' => [ 'id' => ['edit-output'], ], ]; $elem2 = [ '#type' => 'textfield', '#title' => '', '#size' => '20', '#value' => $num, '#attributes' => [ 'id' => ['edit-output2'], ], ]; $elem3 = [ '#type' => 'textarea', '#title' => '', '#value' => $des, '#rows' => 3, '#cols' => 30, '#required' => FALSE, '#attributes' => [ 'id' => ['edit-output3'], ], ]; $renderer = \Drupal::service('renderer'); $response->addCommand(new ReplaceCommand('#edit-output', $renderer->render($elem))); $response->addCommand(new ReplaceCommand('#edit-output2', $renderer->render($elem2))); $response->addCommand(new ReplaceCommand('#edit-output3', $renderer->render($elem3))); } $response->addCommand(new CssCommand("[name=$nomcible]", $css)); $response->AddCommand(new HtmlCommand('#error-message-txt_reference', $message)); return $response; }
Ce code fonctionne 'en apparence' à merveille. J'obtiens bien ce que je veux, à savoir, l'apparition des trois valeurs connues dans leur champ respectif.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46 $form['label_type_modele'] = [ '#type' => 'markup', '#markup' => $this->t('Type ou modèle :'), ]; $form['type_modele'] = [ '#type' => 'textfield', '#title' => '', '#size' => '20', '#attributes' => [ 'id' => ['edit-output'], ], ]; $form['saut_col3'] = [ '#type' => 'markup', '#markup' => $this->t('</td><td style="border:none;">'), ]; $form['label_numserie'] = [ '#type' => 'markup', '#markup' => $this->t('N° de série :'), ]; $form['numserie'] = [ '#type' => 'textfield', '#title' => '', '#size' => '20', '#required' => FALSE, '#attributes' => [ 'id' => ['edit-output2'], ], ]; $form['t2_ferme'] = [ '#type' => 'markup', '#markup' => $this->t('</td></tr></table>'), ]; $form['label_description'] = [ '#type' => 'markup', '#markup' => $this->t('Description :'), ]; $form['description'] = [ '#type' => 'textarea', '#title' => '', '#rows' => 3, '#required' => FALSE, '#attributes' => [ 'id' => ['edit-output3'], ], ];
Cependant, au submit (click sur enregistrer), les champs texte correspondants à ces trois valeurs récupérées sont vides ???
Mes trois variables sont vides contrairement aux champs qui ont été renseignés manuellement et que je récupère exactement de la même manière ?....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 public function submitForm(array &$form, FormStateInterface $form_state) { $rep = $form_state->getValue('type_modele'); $num = $form_state->getValue('numserie'); $des = $form_state->getValue('description'); ... ...
J'en conclu que je ne fais pas les choses correctement. J'ai tenté différentes variantes (HtmlCommand, InvokeCommand, etc...), rien n'y fait. Je ne vois pas comment je peux remplir ces champs depuis mon callback ajax et faire en sorte que mon submit les récupère.
Si quelqu'un peut m'aider, me conseiller cela m'avancerai sérieusement.
En résumé, comment après avoir saisi ma référence je peux remplir mes champs texte de sorte que mon submit puisse les récupérer ?
Merci à vous.
Partager