Skąd mam wiedzieć, który przycisk został kliknięty?

12

Mam formularz z przyciskami „Prześlij” i „Anuluj”. W hook_submit(), skąd mam wiedzieć, który przycisk został kliknięty?

użytkownik1359
źródło
Mówisz o programie hook_submit()obsługi formularzy? Procedura obsługi przesyłania formularzy nie jest implementacją hook_submit().
kiamlaluno

Odpowiedzi:

23

Musisz użyć triggering_elementz $form_state['triggering_element'].

Najlepszą praktyką jest zdefiniowanie #nameatrybutu dla przycisku, aby można było mieć tę wartość w triggering_element.

Na przykład:

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

Jeśli nie zdefiniujesz tego atrybutu, triggering_elementbędzie on zawierał przycisk #value(tekst, który użytkownik może przeczytać), ale jest to odradzane, ponieważ inne moduły mogą zmienić tę wartość lub zmienić lokalizację.

Możesz także użyć $form_state['clicked_button'], ale jest to przestarzałe .

Możesz przeczytać więcej informacji na stronie dokumentacji funkcji drupal_build_form .

sanzante
źródło
7

$form_state['clicked_button']['#value'] powie Ci, który przycisk został kliknięty w formularzu.

iStryker
źródło
$form_state['clicked_button']['#value']:)
user1359,
1
Chciałbym dodać, jeśli masz wymagane pola w formularzu i nie są one wypełnione, wtedy Drupal zgłosi błąd sprawdzania poprawności formularza (formularz_submit jest wywoływany po form_validate). Musisz zrobić coś takiego: devengineering.com/best-practices/drupal/…
iStryker
Trafne spostrzeżenie!
user1359,
5
Chociaż przycisk „clicked_button” nadal działa, został on przestarzały w D7, a zaleceniem jest użycie zamiast niego „triggering_element”. Pamiętam, że było kilka błędów #ajax (myślę), które wpłynęły tylko na kod, który używał „clicked_button”, więc jest to jeszcze jeden powód, aby używać „triggering_element”. A w końcu to po prostu inny klucz w $ form_state.
Bojan Zivanovic
1
Chociaż to podejście działa, jest przestarzałe i podatne na problemy. Zobacz odpowiedź tuniki, aby znaleźć właściwy sposób na zrobienie tego.
Alice Heaton,
3

Porównaj te wartości w $form_stateI robiłem w Drupal 6 i będą takie same w 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
}
Shoaib Nawaz
źródło
Jeśli dobrze pamiętam, Drupal 6 $ form_state] ['X'] jest teraz $ form_state ['X'] w Drupal 7
iStryker
Dlaczego musisz porównać te dwie wartości?
iStryker
Jeśli formularz zawiera wiele przycisków przesyłania. To porównanie pomoże odróżnić przycisk użyty do przesłania formularza w jednym module obsługi przesyłania. $ form_state ['clicked_button'] ['# value'] = t ('Yes') przyniesie różne wartości w konfiguracji wielojęzycznej.
Shoaib Nawaz
Pojedyncze porównanie najlepiej uniknąć wszystkich porównań językowych w konfiguracji wielojęzycznej. :)
Shoaib Nawaz
1
@ iStryker Nie jestem pewien, co masz na myśli przez swój pierwszy komentarz.
kiamlaluno
3

Nazwij przyciski #nameatrybutem, na przykład:

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

a następnie użyj:

$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.
użytkownik13097
źródło
Tak więc dla formularza z dwoma przyciskami wysyłania, takimi jak ten: $ form ['subm'] = array ('#type' => 'subm', '#name' => 'subm-1', '#value' => t („Prześlij1”),); $ form ['subm2'] = array ('#type' => 'subm', '#name' => 'subm-2', '#value' => t ('Submit2'),); Musimy tylko sprawdzić $ form_state-> getTriggeringElement () ['# name'] w funkcji SubmitForm ()?
Gajusz
3

AKTUALIZACJA 2016 Drupal 8

Dla tych, którzy wciąż próbują dowiedzieć się, jak uzyskać dostęp do wyzwalanego zdarzenia, oto rozwiązanie Drupal 8.

$form_state->getTriggeringElement()

Zwraca tablicę wyzwalającego elementu wysyłającego. Jeśli dodasz znacznik o nazwie, #nameuzyskasz do niego dostęp w następujący sposób.

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

Powodem tej zmiany jest FormStateInterfaceteraz readOnlyplik, w którym tylko rozszerzające się klasy FormStateInterfacemogą uzyskać dostęp do zmiennych. Musisz więc użyć metod akcesora, takich jak getTriggeringElement()w celu uzyskania dostępu do zmiennej.

Neoaptt
źródło
Mam aktualizację dla Drupal 8.4.4 w 2018 roku: drupal.stackexchange.com/a/256112/1441
user1359
0

W Drupal 8.4.4 $form_state->getTriggeringElement()['#name'];daje ci wartość op. Kiedy szukasz tego klucza w tablicy wartości stanu formularza, dostajesz #valueklucz elementu postaci przycisku - innymi słowy ciąg znaków, który użytkownicy końcowi widzą na przycisku na stronie.

Nie wiem, czy $form_state->getValues()['op']jest uniwersalny dla wszystkich form, ale koduję go na stałe w formie mojego modułu.

użytkownik1359
źródło
0

Drupal 8.6.7

Utwórz przycisk podobny do poniższego.

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

W funkcji wysyłania pobierz nazwę przycisku jak poniżej kodu.

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

Porównanie można wykonać jak

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

# Drupal8

Yogesh Kushwaha
źródło