Как я могу узнать, какая кнопка была нажата?


12

У меня есть форма с кнопками «Отправить» и «Отмена». В hook_submit(), как я знаю , какая кнопка была нажата?


Вы говорите hook_submit()или обработчик представления формы? Обработчик представления формы не является реализацией hook_submit().
kiamlaluno

Ответы:


23

Вы должны использовать triggering_elementиз $form_state['triggering_element'].

Рекомендуется определить #nameатрибут для вашей кнопки, чтобы вы могли иметь это значение в triggering_element.

Например:

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

Если вы не определите этот атрибут, он triggering_elementбудет содержать кнопку #value(текст, который может прочитать пользователь), но это не рекомендуется, так как другие модули могут изменить это значение или изменить его в результате локализации).

Вы также можете использовать $form_state['clicked_button'], но это не рекомендуется .

Вы можете прочитать больше информации на странице документации по функции drupal_build_form .


7

$form_state['clicked_button']['#value'] скажет вам, какая кнопка была нажата в форме.


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

1
Я хотел бы добавить, что если у вас есть обязательные поля в вашей форме, и они не заполнены, то ваш Drupal выдаст ошибку проверки формы (form_submit вызывается после form_validate). Вам нужно сделать что - то вроде этого devengineering.com/best-practices/drupal/...
iStryker

Неплохо подмечено!
user1359

5
Хотя «clicked_button» все еще работает, в D7 он устарел, и вместо него рекомендуется использовать «triggering_element». Я помню, что были некоторые ошибки #ajax (я думаю), которые влияли только на код, который использовал "clicked_button", так что это еще одна причина использовать "triggering_element". И в конце концов, это просто другой ключ в $ form_state.
Боян Живанович

1
Хотя этот подход работает, он устарел и подвержен проблемам. См. Ответ туники для правильного Drupal 7 способ сделать это.
Алиса Хитон

3

Сравните эти значения в $form_stateDrupal 6, и в 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
}

Если я правильно помню, Drupal 6 $ form_state] ['X'] теперь является $ form_state ['X'] в Drupal 7
iStryker

Зачем вам нужно сравнивать эти два значения?
iStryker

Если форма содержит несколько кнопок отправки. Это сравнение поможет отличить, какая кнопка используется для отправки формы в одном обработчике отправки. $ form_state ['clicked_button'] ['# value'] = t ('Yes') приведет к различным значениям при многоязычной настройке.
Шоаиб Наваз

Одиночное сравнение лучше всего избегать всех языковых сравнений при многоязычной настройке. :)
Шоаиб Наваз

1
@iStryker Я не уверен, что вы имеете в виду с вашим первым комментарием.
kiamlaluno

3

Назовите кнопки с #nameатрибутом, например так:

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

а затем используйте:

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

Итак, для формы с двумя кнопками отправки, например: $ form ['submit'] = array ('#type' => 'submit', '#name' => 'submit-1', '#value' => t («Submit1»),); $ form ['submit2'] = array ('#type' => 'submit', '#name' => 'submit-2', '#value' => t ('Submit2'),); Нам просто нужно проверить $ form_state-> getTriggeringElement () ['# name'] в функции submitForm ()?
Гай

3

ОБНОВЛЕНИЕ 2016 Drupal 8

Для тех, кто все еще пытается выяснить, как получить доступ к сработавшему событию, вот решение Drupal 8.

$form_state->getTriggeringElement()

Это возвращает массив инициирующего элемента submit. Если вы добавите разметку с названием, #nameвы получите доступ к ней следующим образом.

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

Причина этого изменения в том, что FormStateInterfaceтеперь это readOnlyфайл, в котором только классы, которые расширяются, FormStateInterfaceмогут получить доступ к переменным. Таким образом, вы должны использовать методы доступа, как getTriggeringElement()для доступа к переменной.


У меня есть обновление для Drupal 8.4.4 в 2018 году: drupal.stackexchange.com/a/256112/1441
user1359

0

В Drupal 8.4.4 выдается $form_state->getTriggeringElement()['#name'];значение op. Когда вы ищите этот ключ в массиве значений состояния формы, вы получаете #valueключ элемента формы кнопки - другими словами, строку, которую конечные пользователи видят на кнопке на странице.

Я не знаю, $form_state->getValues()['op']универсален ли он для всех форм, но я жестко кодирую его в форме моего модуля.


0

Drupal 8.6.7

Создать кнопку что-то вроде ниже.

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

В вашей функции отправки введите имя кнопки, как показано ниже.

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

Сравнение можно сделать как

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

# Drupal8

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.