Bagaimana saya bisa menerapkan pengiriman formulir AJAX?

14

Tugas saya adalah mengirimkan formulir kontak melalui AJAX dan kemudian menunjukkan "Terima kasih atas pengiriman!" pesan, dimuat di tempat formulir itu. Jadi saya perlu memperbarui formulir kontak yang ada.

Saya menemukan beberapa contoh cara memvalidasi bidang formulir menggunakan AJAX di D8, tetapi saya tidak dapat menemukan contoh bagaimana menerapkan pengiriman formulir ajax dan memuat beberapa konten melalui AJAX kemudian.

Bagaimana saya bisa mengimplementasikan tugas saya? Bagaimana cara saya mengubah formulir kontak untuk menambahkan fungsionalitas yang diperlukan?

Sergey Kravchenko
sumber
Bagi mereka yang datang ke sini dengan pertanyaan formulir umum: Modul Webform memungkinkan Anda untuk membuat formulir seperti yang Anda inginkan dan membiarkan hasilnya diserahkan melalui ajax.
Florian Müller

Jawaban:

26

Ketika bekerja dengan ajax dalam bentuk, Anda harus mengingat hal-hal berikut:

  • tahu apakah Anda membangun kembali seluruh formulir atau hanya sebagian dan bungkus formulir sesuai dengan elemen div yang memiliki atribut ID yang akan Anda gunakan dalam definisi #ajax pada elemen pemicu sebagai 'bungkus'. Gunakan atribut #prefix dan #suffix untuk ini ( $form['#prefix'] = '<div id="myform-ajax-wrapper">'; $form['#suffix'] = '</div>';). Juga perlu diingat bahwa jika Anda memiliki templat kustom untuk formulir Anda untuk TIDAK membuat awalan dan akhiran dalam kasus ini ( {{ form|without('#prefix', '#suffix') }}) kalau tidak mereka akan dirender dua kali - oleh templat Anda dan juga oleh pembungkus tema form. Anda tidak dapat mencegah ini dengan menetapkan #theme_wrappers untuk mengosongkan array karena Templat formulir berisi elemen html formulir yang sebenarnya.

  • di ajax kirim handler Anda, kembalikan seluruh formulir atau bagiannya yang telah Anda bungkus dan ingin dibangun kembali ( return $formatau return $form['myelement']). Anda juga dapat menggunakan perintah ajax bukan hanya mengembalikan struktur formulir tetapi itu adalah hal yang lebih maju.

  • menyimpan setiap nilai dalam penyimpanan kondisi formulir sampai Anda mengirimkan formulir. Lakukan ini di pengirim handler ( $form_state->set('somevalue', $form_state->getValue('somevalue'))) dan selalu panggil $form_state->setRebuild()jika Anda tidak melakukan pengiriman formulir akhir. Saya lebih suka memiliki penangan pengiriman kustom tetapi memiliki lebih banyak logika dalam penangan pengiriman utama juga ok.

  • selalu gunakan #nameatribut pada tombol yang melakukan pengiriman dan jika Anda hanya memiliki satu formulir kirim gunakan handler $for_state->getTriggeringElement()['#name']untuk mendeteksi elemen mana yang telah mengirimkan formulir.

  • jika Anda menggunakan 'trigger_as' dalam definisi #ajax, jika Anda ingin mengirimkan formulir dengan elemen pilih misalnya, selalu gunakan definisi #ajax yang sama seperti yang Anda lakukan pada tombol. Dalam pengalaman saya itu diperlukan - meskipun tidak disebutkan dalam dokumentasi.

  • menggunakan #limit_validation_errorskadang-kadang bisa sangat rumit dan untuk mencari tahu mengapa formulir tidak berfungsi bisa memakan waktu cukup lama, jadi gunakan dengan hati-hati (ini bagus untuk mengisolasi kesalahan formulir hanya pada elemen yang Anda benar-benar buat kembali sehingga kode Anda tidak mempengaruhi bagian lain dari formulir).

  • selalu gunakan tombol untuk mengirimkan formulir dan jika Anda ingin memiliki sesuatu yang mewah, seperti memilih menjadi elemen pemicu, gunakan opsi 'trigger_as' dari konfigurasi #ajax dan sembunyikan tombol nyata dengan kelas 'js-hide' untuk UI yang bagus.

  • dalam definisi formulir, dapatkan nilai default dari penyimpanan kondisi formulir jika ada atau tetapkan ke dalam penyimpanan jika tidak ada. Kalau tidak, formulir tidak akan berfungsi dengan baik.

  • jangan gunakan $ this atau apa pun yang Anda tidak memiliki akses ke luar, jika tidak akan merusak ajax. selalu menggunakan penangan ajax statis.

  • ketika akhirnya mengirimkan formulir, tergantung pada kenyataan bahwa Anda (tidak) memiliki penangan pengiriman formulir kustom untuk ajax, nonaktifkan formulir pembangunan kembali dengan memanggil $form_state->setRebuild(FALSE).

  • Anda dapat menggunakan :: panggilan singkat dalam elemen pengiriman ajax ( $element['#ajax']['callback'] = '::ajaxFormRebuild';dan $element['#submit'] = [['::ajaxFormSubmitHandler'];).

  • panggilan balik ajax murni untuk mengembalikan formulir yang dibangun kembali atau perintah ajax. Jangan pernah mengembalikan formulir yang diubah (mis. Jangan mengubah form array di panggilan balik ini).


sumber
Daftar periksa hebat, jika Anda memiliki masalah dengan ajax di drupal 8! (Saya tidak mengerti poin pertama, mengapa TIDAK membuat ajax wrap div?)
4k4
Saya tidak ingat persis tetapi saya pikir itu mungkin ada hubungannya dengan #theme, #theme_wrappers dan penanganan atribut #prefix dan #suffix di renderer. Saya pikir Anda akan berakhir dengan pembungkus di dalam elemen <form>. Ini tentu saja berlaku hanya jika Anda membangun kembali seluruh formulir, bukan hanya beberapa elemen.
Terima kasih, tetapi di mana saya dapat menemukan contoh sederhana untuk pengiriman AJAX?
Sergey Kravchenko
@IvanJaros, terima kasih. Apakah Anda tahu cara menghapus nilai formulir setelah pengajuan ajax?
milkovsky
1

Untuk menambah daftar periksa ini, jika Anda menampilkan formulir di jendela modal ada kemungkinan bahwa pesan kesalahan tidak akan ditampilkan. Seperti yang dikatakan Ivan Jaros, Anda harus memastikan bahwa formulir tersebut memiliki pembungkus:

$form['#prefix'] = '<div id="my-form-wrapper-id">';
$form['#suffix'] = '</div>';

Anda juga harus menambahkan yang berikut ini ke elemen yang mengirimkan formulir. Dalam kebanyakan kasus itu akan menjadi tombol kirim Anda:

$form['submit'] = [
    '#type' => 'submit',
    '#value' => $this->t('Save Changes'),
    '#attributes' => [
        'class' => [
            'btn',
            'btn-md',
            'btn-primary',
            'use-ajax-submit'
        ]
    ],
    '#ajax' => [
        'wrapper' => 'my-form-wrapper-id',
    ]
];
IslandDev
sumber
1

Saya menggunakan modul Contact ajax . Beberapa detail lebih lanjut tentang hal itu (dari halaman proyeknya):

Kontak Ajax mengimplementasikan pengajuan ajax untuk formulir Kontak di Drupal 8.

Bagaimana itu bekerja

Setelah mengaktifkan modul, setiap formulir kontak akan menampilkan kotak centang "Gunakan ajax". Ketika kotak centang ini diaktifkan, formulir kontak akan menunjukkan kepada Anda opsi lain "Jenis konfirmasi" dengan opsi-opsi ini:

  • Muat formulir: akan mengirim formulir tanpa memuat ulang halaman.
  • Muat dari pesan khusus: muat teks khusus.
  • Memuat dari simpul: memuat simpul setelah pengiriman formulir.

Modul ini dapat membantu Anda jika:

  • Anda perlu menyesuaikan pesan konfirmasi
  • Anda perlu mengirimkan formulir kontak tanpa memuat ulang halaman.
  • Anda ingin memuat teks khusus atau simpul lain setelah pengiriman formulir.
Masdzen
sumber