Bagaimana saya bisa tahu tombol mana yang diklik?

12

Saya memiliki formulir dengan tombol "Kirim" dan "Batalkan". Di hook_submit(), bagaimana saya tahu tombol mana yang diklik?

pengguna1359
sumber
Apakah Anda berbicara tentang hook_submit()atau pengajuan formulir pendaftaran? Penangan pengajuan formulir bukan implementasi dari hook_submit().
kiamlaluno

Jawaban:

23

Anda harus menggunakan triggering_elementdari $form_state['triggering_element'].

Praktik terbaik adalah mendefinisikan #nameatribut untuk tombol Anda, sehingga Anda dapat memiliki nilai ini di triggering_element.

Sebagai contoh:

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

Jika Anda tidak mendefinisikan atribut ini triggering_elementakan menahan tombol #value(teks yang dapat dibaca pengguna), tetapi ini tidak disarankan karena modul lain dapat mengubah nilai ini atau diubah oleh lokalisasi).

Anda dapat menggunakan $form_state['clicked_button']juga, tetapi ini sudah usang .

Anda dapat membaca info lebih lanjut di halaman dokumentasi fungsi drupal_build_form .

sanzante
sumber
7

$form_state['clicked_button']['#value'] akan memberi tahu Anda tombol mana yang diklik pada formulir.

iStryker
sumber
$form_state['clicked_button']['#value']:)
user1359
1
Saya ingin menambahkan, jika Anda membutuhkan bidang pada formulir Anda, dan mereka tidak diisi, maka Anda Drupal akan melemparkan kesalahan validasi formulir (form_submit dipanggil setelah form_validate). Anda perlu melakukan sesuatu seperti devengineering.com/best-practices/drupal/…
iStryker
Itu poin yang bagus!
user1359
5
Sementara "clicked_button" masih berfungsi, itu sudah usang di D7 dan rekomendasinya adalah menggunakan "triggering_element" sebagai gantinya. Saya ingat ada beberapa bug #ajax (saya pikir) yang hanya memengaruhi kode yang menggunakan "clicked_button", jadi itu satu lagi alasan untuk menggunakan "triggering_element". Lagi pula, itu hanya kunci yang berbeda di $ form_state.
Bojan Zivanovic
1
Sementara pendekatan ini bekerja, itu sudah usang dan rentan terhadap masalah. Lihat jawaban tunik untuk cara Drupal 7 yang benar untuk melakukan ini.
Alice Heaton
3

Bandingkan nilai-nilai ini di $form_statesaya telah lakukan di Drupal 6 dan akan sama di 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
sumber
Jika saya ingat benar Drupal 6 $ form_state] ['X'] sekarang $ form_state ['X'] di Drupal 7
iStryker
Mengapa Anda perlu membandingkan kedua nilai ini?
iStryker
Jika formulir berisi beberapa tombol kirim. Perbandingan ini akan membantu membedakan tombol mana yang digunakan untuk mengirimkan formulir dalam penangan pengiriman tunggal. $ form_state ['clicked_button'] ['# value'] = t ('Ya') akan menghasilkan nilai yang berbeda pada pengaturan multibahasa.
Shoaib Nawaz
Perbandingan tunggal adalah yang terbaik untuk menghindari semua perbandingan bahasa dalam pengaturan multibahasa. :)
Shoaib Nawaz
1
@ iStryker Saya tidak yakin apa yang Anda maksud dengan komentar pertama Anda.
kiamlaluno
3

Beri nama tombol dengan #nameatribut, seperti ini:

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

lalu gunakan:

$values = $form_state['input'];
if (isset($values['delete'])) // 'delete' button was pressed.
pengguna13097
sumber
Jadi untuk formulir dengan dua tombol kirim seperti ini: $ form ['submit'] = array ('#type' => 'submit', '#name' => 'submit-1', '#value' => t ('Kirim1'),); $ form ['submit2'] = array ('#type' => 'submit', '#name' => 'submit-2', '#value' => t ('Kirim2'),); Kita hanya perlu memeriksa $ form_state-> getTriggeringElement () ['# name'] di fungsi submitForm ()?
Gayus
3

UPDATE 2016 Drupal 8

Bagi mereka yang masih mencoba mencari cara untuk mengakses peristiwa yang dipicu di sini adalah solusi Drupal 8.

$form_state->getTriggeringElement()

Ini mengembalikan array elemen pengiriman yang memicu. Jika Anda menambahkan markup yang dipanggil #namemaka Anda akan mengaksesnya dengan cara berikut.

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

Alasan di balik perubahan ini adalah bahwa FormStateInterfacesekarang readOnlyfile di mana hanya kelas yang memperluas FormStateInterfacedapat mengakses variabel. Jadi, Anda harus menggunakan metode accessor seperti getTriggeringElement()untuk mengakses variabel.

Neoaptt
sumber
Saya memiliki pembaruan untuk Drupal 8.4.4 di 2018: drupal.stackexchange.com/a/256112/1441
user1359
0

Dalam Drupal 8.4.4 $form_state->getTriggeringElement()['#name'];memberi Anda nilai op. Saat Anda mencari kunci itu di array nilai bentuk keadaan, Anda mendapatkan #valuekunci elemen bentuk tombol-- dengan kata lain, string yang dilihat pengguna akhir pada tombol di halaman.

Saya tidak tahu apakah $form_state->getValues()['op']itu universal untuk semua bentuk, tapi saya mengkodekannya dalam bentuk modul.

pengguna1359
sumber
0

Drupal 8.6.7

Buat tombolnya seperti di bawah ini.

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

Dalam fungsi kirim Anda dapatkan nama tombol seperti kode di bawah ini.

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

Perbandingan dapat dilakukan seperti

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

# Drupal8

Yogesh Kushwaha
sumber