Come posso sapere quale pulsante è stato cliccato?


12

Ho un modulo con i pulsanti "Invia" e "Annulla". In hook_submit(), come faccio a sapere quale pulsante è stato cliccato?


Stai parlando di hook_submit()un gestore di invio moduli? Un gestore di invio di moduli non è l'implementazione di hook_submit().
kiamlaluno

Risposte:


23

È necessario utilizzare il triggering_elementda $form_state['triggering_element'].

La migliore pratica è definire un #nameattributo per il tuo pulsante, in modo da poter avere questo valore in triggering_element.

Per esempio:

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

Se non si definisce questo attributo triggering_elementconterrà il pulsante #value(il testo che l'utente può leggere), ma questo è sconsigliato in quanto altri moduli possono cambiare questo valore o essere modificati dalla localizzazione).

Puoi $form_state['clicked_button']anche usare , ma questo è deprecato .

Puoi leggere maggiori informazioni nella pagina di documentazione della funzione drupal_build_form .


7

$form_state['clicked_button']['#value'] ti dirà quale pulsante è stato fatto clic sul modulo.


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

1
Mi piace aggiungere, se hai richiesto i campi sul tuo modulo e non sono compilati, allora Drupal genererà un errore di convalida del modulo (form_submit viene chiamato dopo form_validate). Devi fare qualcosa del genere devengineering.com/best-practices/drupal/…
iStryker

È un buon punto!
user1359

5
Mentre "clicked_button" funziona ancora, è stato deprecato in D7 e si consiglia invece di utilizzare "triggering_element". Ricordo che c'erano alcuni bug #ajax (penso) che riguardavano solo il codice che utilizzava "clicked_button", quindi questo è un motivo in più per usare "triggering_element". Dopotutto, è solo una chiave diversa in $ form_state.
Bojan Zivanovic,

1
Mentre questo approccio funziona, è deprecato e soggetto a problemi. Vedi la risposta della tunica per il modo corretto di Drupal 7 di farlo.
Alice Heaton,

3

Confronta questi valori in $form_stateHo fatto in Drupal 6 e sarebbe lo stesso in 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
}

Se ricordo correttamente Drupal 6 $ form_state] ['X'] ora è $ form_state ['X'] in Drupal 7
iStryker,

Perché è necessario confrontare questi due valori?
iStryker,

Se il modulo contiene più pulsanti di invio. Questo confronto aiuterà a differenziare il pulsante utilizzato per inviare il modulo in un unico gestore di invio. $ form_state ['clicked_button'] ['# value'] = t ('Yes') produrrà valori diversi sulla configurazione multilingue.
Shoaib Nawaz,

È preferibile un singolo confronto per evitare tutti i confronti linguistici nella configurazione multilingue. :)
Shoaib Nawaz,

1
@iStryker Non sono sicuro di cosa intendi con il tuo primo commento.
kiamlaluno

3

Assegna un nome ai pulsanti con l' #nameattributo, in questo modo:

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

e quindi usa:

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

Quindi per un modulo con due pulsanti di invio come questo: $ form ['submit'] = array ('#type' => 'submit', '#name' => 'submit-1', '#value' => t ('Submit1'),); $ form ['submit2'] = array ('#type' => 'submit', '#name' => 'submit-2', '#value' => t ('Submit2'),); Dobbiamo solo controllare $ form_state-> getTriggeringElement () ['# name'] nella funzione submitForm ()?
Gaius,

3

AGGIORNAMENTO 2016 Drupal 8

Per coloro che stanno ancora cercando di capire come accedere all'evento attivato, ecco la soluzione Drupal 8.

$form_state->getTriggeringElement()

Ciò restituisce l'array dell'elemento di invio del trigger. Se aggiungi un markup chiamato, accederai #namenel modo seguente.

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

Il motivo dietro questa modifica è che FormStateInterfaceora è un readOnlyfile in cui solo le classi estese FormStateInterfacepossono accedere alle variabili. Quindi devi usare metodi getTriggeringElement()di accesso come per accedere alla variabile.


Ho un aggiornamento per Drupal 8.4.4 nel 2018: drupal.stackexchange.com/a/256112/1441
user1359

0

In Drupal 8.4.4 $form_state->getTriggeringElement()['#name'];ti dà il valore di op. Quando cerchi quella chiave nell'array dei valori dello stato del modulo, ottieni la #valuechiave dell'elemento del modulo pulsante, in altre parole, la stringa che gli utenti finali vedono sul pulsante nella pagina.

Non so se $form_state->getValues()['op']sia universale per tutti i moduli, ma lo sto codificando nella forma del mio modulo.


0

Drupal 8.6.7

Pulsante Crea qualcosa di simile al di sotto.

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

Nella tua funzione di invio ottieni il nome del pulsante come sotto il codice.

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

Il confronto può essere fatto come

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

# Drupal8

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.