¿Cómo puedo saber en qué botón se hizo clic?

12

Tengo un formulario con los botones "Enviar" y "Cancelar". En hook_submit(), ¿cómo sé en qué botón se hizo clic?

usuario1359
fuente
¿Estás hablando de hook_submit()un controlador de envío de formularios? Un controlador de envío de formularios no es la implementación de hook_submit().
kiamlaluno

Respuestas:

23

Debe usar el triggering_elementde $form_state['triggering_element'].

La mejor práctica es definir un #nameatributo para su botón, para que pueda tener este valor en el triggering_element.

Por ejemplo:

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

Si no define este atributo, triggering_elementse mantendrá el botón #value(el texto que el usuario puede leer), pero esto se desaconseja ya que otros módulos pueden cambiar este valor o la localización puede cambiarlo.

También puede usar $form_state['clicked_button'], pero esto está en desuso .

Puede leer más información en la página de documentación de la función drupal_build_form .

sanzante
fuente
7

$form_state['clicked_button']['#value'] le dirá en qué botón se hizo clic en el formulario.

iStryker
fuente
$form_state['clicked_button']['#value']:)
user1359
1
Me gusta agregar, si ha requerido campos en su formulario, y no están completados, entonces Drupal arrojará un error de validación de formulario (se llama a form_submit después de form_validate). Debe
iStryker
¡Ese es un buen punto!
user1359
55
Si bien "clicked_button" aún funciona, ha quedado en desuso en D7 y la recomendación es utilizar "triggering_element" en su lugar. Recuerdo que había algunos errores #ajax (creo) que solo afectaban al código que usaba "clicked_button", así que esa es una razón más para usar "triggering_element". Y después de todo, es solo una clave diferente en $ form_state.
Bojan Zivanovic
1
Si bien este enfoque funciona, es obsoleto y propenso a problemas. Vea la respuesta de la túnica para la forma correcta de Drupal 7 de hacer esto.
Alice Heaton
3

Compare estos valores en lo $form_stateque he estado haciendo en Drupal 6 y sería lo mismo en 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
fuente
Si recuerdo correctamente Drupal 6 $ form_state] ['X'] ahora es $ form_state ['X'] en Drupal 7
iStryker
¿Por qué necesitas comparar estos dos valores?
iStryker
Si el formulario contiene varios botones de envío. Esta comparación ayudará a diferenciar qué botón se usó para enviar el formulario en un solo controlador de envío. $ form_state ['clicked_button'] ['# value'] = t ('Yes') dará como resultado valores diferentes en la configuración multilingüe.
Shoaib Nawaz
Una mejor comparación es mejor para evitar todas las comparaciones de idiomas en una configuración multilingüe. :)
Shoaib Nawaz
1
@ iStryker No estoy seguro de lo que quieres decir con tu primer comentario.
kiamlaluno
3

Nombre los botones con el #nameatributo, así:

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

y luego usa:

$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.
usuario13097
fuente
Entonces, para un formulario con dos botones de envío como este: $ form ['submit'] = array ('#type' => 'submit', '#name' => 'submit-1', '#value' => t ('Enviar1'),); $ form ['submit2'] = array ('#type' => 'submit', '#name' => 'submit-2', '#value' => t ('Submit2'),); Solo tenemos que verificar $ form_state-> getTriggeringElement () ['# name'] en la función submitForm ()?
Cayo el
3

ACTUALIZACIÓN 2016 Drupal 8

Para aquellos que todavía intentan descubrir cómo acceder al evento activado, aquí está la solución Drupal 8.

$form_state->getTriggeringElement()

Esto devuelve la matriz del elemento de envío desencadenante. Si agrega un marcado llamado #name, accedería a él de la siguiente manera.

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

La razón detrás de este cambio es que FormStateInterfaceahora es un readOnlyarchivo en el que solo las clases que se extienden FormStateInterfacepueden acceder a las variables. Por lo tanto, debe usar métodos getTriggeringElement()de acceso como para acceder a la variable.

Neoaptt
fuente
Tengo una actualización para Drupal 8.4.4 en 2018: drupal.stackexchange.com/a/256112/1441
user1359
0

En Drupal 8.4.4 $form_state->getTriggeringElement()['#name'];le da el valor de op. Cuando busca esa clave en la matriz de valores del estado del formulario, obtiene la #valueclave del elemento de formulario del botón; en otras palabras, la cadena que los usuarios finales ven en el botón de la página.

No sé si $form_state->getValues()['op']es universal para todas las formas, pero lo estoy codificando en la forma de mi módulo.

usuario1359
fuente
0

Drupal 8.6.7

Crear botón algo como a continuación.

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

En su función de envío, obtenga el nombre del botón como el código a continuación.

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

La comparación se puede hacer como

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

# Drupal8

Yogesh Kushwaha
fuente