Comment savoir quel bouton a été cliqué?


12

J'ai un formulaire avec un bouton "Soumettre" et un bouton "Annuler". Dans hook_submit(), comment savoir quel bouton a été cliqué?


Parlez-vous hook_submit()ou d'un gestionnaire de soumission de formulaire? Un gestionnaire de soumission de formulaire n'est pas l'implémentation de hook_submit().
kiamlaluno

Réponses:


23

Vous devez utiliser le à triggering_elementpartir du $form_state['triggering_element'].

La meilleure pratique consiste à définir un #nameattribut pour votre bouton, afin que vous puissiez avoir cette valeur dans le triggering_element.

Par exemple:

$form['delete'] = array(
  '#type' => 'submit',
  '#value' => t('Delete'),
  '#name' => 'delete',
);

Si vous ne définissez pas cet attribut triggering_elementcontiendra le bouton #value(le texte que l'utilisateur peut lire), mais cela est déconseillé car d'autres modules peuvent modifier cette valeur ou être modifié par la localisation).

Vous pouvez $form_state['clicked_button']également l' utiliser , mais cela est obsolète .

Vous pouvez lire plus d'informations sur la page de documentation de la fonction drupal_build_form .


7

$form_state['clicked_button']['#value'] vous dira quel bouton a été cliqué sur le formulaire.


$form_state['clicked_button']['#value']:)
user1359

1
J'aime ajouter, si vous avez requis des champs sur votre formulaire, et qu'ils ne sont pas remplis, alors vous Drupal lancera une erreur de validation de formulaire (form_submit est appelé après form_validate). Vous devez faire quelque chose comme ceci devengineering.com/best-practices/drupal/…
iStryker

C'est un bon point!
user1359

5
Bien que "clicked_button" fonctionne toujours, il est déconseillé dans D7 et la recommandation est d'utiliser à la place "triggering_element". Je me souviens qu'il y avait des bogues #ajax (je pense) qui affectaient uniquement le code qui utilisait "clicked_button", c'est donc une raison de plus pour utiliser "triggering_element". Et après tout, c'est juste une clé différente dans $ form_state.
Bojan Zivanovic

1
Bien que cette approche fonctionne, elle est déconseillée et sujette à des problèmes. Voir la réponse de tunique pour la bonne façon de faire Drupal 7.
Alice Heaton

3

Comparer ces valeurs dans $form_stateJ'ai fait dans Drupal 6 et serait la même dans Drupal7

if($form_state['values']['ok'] == $form_state]['clicked_button']['#value']){
    //Process if OK is pressed
}else if($form_state['values']['cancel'] == $form_state]['clicked_button']['#value']) {
    //Process if Cancel is pressed
}

Si je me souviens bien, Drupal 6 $ form_state] ['X'] est maintenant $ form_state ['X'] dans Drupal 7
iStryker

Pourquoi avez-vous besoin de comparer ces deux valeurs?
iStryker

Si le formulaire contient plusieurs boutons d'envoi. Cette comparaison aidera à différencier le bouton utilisé pour soumettre le formulaire dans un seul gestionnaire de soumission. $ form_state ['clicked_button'] ['# value'] = t ('Yes') entraînera des valeurs différentes lors de la configuration multilingue.
Shoaib Nawaz

Une comparaison unique est préférable pour éviter toutes les comparaisons de langues dans une configuration multilingue. :)
Shoaib Nawaz

1
@iStryker Je ne sais pas ce que tu veux dire avec ton premier commentaire.
kiamlaluno

3

Nommez les boutons avec l' #nameattribut, comme ceci:

$form['delete'] = array(
    '#type' => 'submit',
    '#value' => t('Delete'),
    '#name' => 'delete',
);

puis utilisez:

$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.

Donc, pour un formulaire avec deux boutons d'envoi comme celui-ci: $ form ['submit'] = array ('#type' => 'submit', '#name' => 'submit-1', '#value' => t («Soumettre1»),); $ form ['submit2'] = array ('#type' => 'submit', '#name' => 'submit-2', '#value' => t ('Submit2'),); Il suffit de vérifier $ form_state-> getTriggeringElement () ['# name'] dans la fonction submitForm ()?
Gaius

3

MISE À JOUR 2016 Drupal 8

Pour ceux qui essaient encore de comprendre comment accéder à l'événement déclenché, voici la solution Drupal 8.

$form_state->getTriggeringElement()

Cela renvoie le tableau de l'élément d'envoi de déclenchement. Si vous ajoutez un balisage appelé, #namevous y accéderez de la manière suivante.

$button_clicked = $form_state->getTriggeringElement()['#name']

La raison de ce changement est qu'il FormStateInterfaces'agit désormais d'un readOnlyfichier dans lequel seules les classes qui s'étendent FormStateInterfacepeuvent accéder aux variables. Vous devez donc utiliser des méthodes d'accesseur comme getTriggeringElement()pour accéder à la variable.


J'ai une mise à jour pour Drupal 8.4.4 en 2018: drupal.stackexchange.com/a/256112/1441
user1359

0

Dans Drupal 8.4.4 $form_state->getTriggeringElement()['#name'];vous donne la valeur de op. Lorsque vous recherchez cette clé dans le tableau de valeurs de l'état du formulaire, vous obtenez la #valueclé de l' élément de formulaire du bouton, en d'autres termes, la chaîne que les utilisateurs finaux voient sur le bouton de la page.

Je ne sais pas si $form_state->getValues()['op']est universel pour toutes les formes, mais je le code en dur dans la forme de mon module.


0

Drupal 8.6.7

Créer un bouton quelque chose comme ci-dessous.

$form['my_button'] = [
    '#type' => 'button',
    '#value' => t('Custom Button'),
    '#name' => t('customButton'),
    '#weight' => 0,
    '#attributes' => [
      'class' => ['populate-bib-button', 'btn', 'btn-primary'],
    ],
  ];

Dans votre fonction d'envoi, obtenez le nom du bouton comme le code ci-dessous.

$input = $form_state->getUserInput();
print $input['_triggering_element_name']; // customButton

La comparaison peut se faire comme

if ($input['_triggering_element_name'] == 'customButton') {
  // Do something.
}

# Drupal8

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.