Events HTMX — HTMX

HTMX menyediakan event system yang kaya untuk custom behavior. Listening Events Load Event Types htmx:beforeRequest — sebelum request dikirim…

htmx memberi kabar di setiap langkah request-nya lewat event DOM: sebelum request dikirim, sesudah balasan ditukar, saat server menolak, dan seterusnya. Kamu bisa mendengarkan event itu untuk menjalankan JavaScript kecil tepat di saat yang pas. Bayangin notifikasi WhatsApp dari Laundry Bu Rini: "cucian diterima", "sedang dicuci", "siap diambil". Kamu gak perlu menelepon untuk bertanya, cukup bereaksi saat pesannya datang. Event htmx adalah pesan-pesan itu, dan addEventListener atau hx-on adalah HP yang menerimanya.

🧪 Tebakan cepat: Order Bu Tini dikirim dan berhasil. Mana yang dikirim htmx lebih dulu: htmx:afterSwap atau htmx:afterRequest? Jawabannya ada di bagian "Urutan event satu request".

Event itu apa

Event htmx adalah event DOM biasa, sama seperti click. htmx mengirimnya ke sebuah elemen, lalu event itu naik (bubble) ke induknya sampai document. Namanya diawali htmx: dan ditulis camelCase, misalnya htmx:afterRequest. htmx juga mengirim versi huruf kecil dengan tanda hubung, htmx:after-request, untuk dipakai di atribut HTML. Detailnya ada di event.detail: elt (elemen yang mengirim), target, xhr (request-nya, misalnya xhr.status), dan successful (true untuk balasan 2xx).

Urutan event satu request

Ini urutan nyata dari htmx 2.0.11 saat form Terima cucian mengirim POST /order dengan target #papan-order:

Event Dikirim ke Kapan
htmx:configRequest form request sedang disusun, parameter dan header masih bisa diubah
htmx:beforeRequest form tepat sebelum dikirim. event.preventDefault() di sini membatalkannya
htmx:beforeSwap #papan-order balasan tiba, belum ditukar
htmx:afterSwap #papan-order balasan sudah ditukar ke halaman
htmx:afterRequest form request selesai
htmx:afterSettle #papan-order 20 ms kemudian, sesudah atribut baru dipasang

htmx:afterSwap datang sebelum htmx:afterRequest. Itu jawaban tebakannya. Kalau server membalas 4xx atau 5xx, urutannya beforeRequest, beforeSwap, htmx:responseError, lalu afterRequest dengan successful: false. Gak ada afterSwap dan afterSettle, karena gak ada yang ditukar.

hx-on: handler langsung di atribut

<form id="terima" hx-post="/order" hx-target="#papan-order" hx-swap="beforeend"
      hx-on::before-request="console.log('Mengirim', event.detail.requestConfig.path)"
      hx-on::after-request="console.log('Selesai', event.detail.xhr.status, event.detail.successful)">

Console sesudah Terima cucian diklik:

Mengirim /order
Selesai 200 true

addEventListener di body

document.body.addEventListener('htmx:afterSwap', (event) => {
  console.log('Ditukar:', event.detail.target.id)   // Ditukar: papan-order
})
document.body.addEventListener('htmx:responseError', (event) => {
  console.log('Gagal:', event.detail.xhr.status)    // Gagal: 500
})

Karena event naik ke atas, satu listener di body mendengar event dari semua elemen, termasuk elemen yang baru ditambahkan lewat swap. htmx:responseError cocok untuk memberi tahu pengguna bahwa server menolak, supaya klik gak terasa mati.

HX-Trigger: server yang memicu event

Server bisa menambahkan header di balasannya: HX-Trigger: orderBaru. Begitu balasan tiba, sebelum swap, htmx memicu event orderBaru di form yang mengirim, dan event itu naik ke body. Di Laravel: return response($html)->header('HX-Trigger', 'orderBaru');.

<span id="jumlah-hari-ini" hx-get="/jumlah" hx-trigger="orderBaru from:body">3 order hari ini</span>

⚠️ Jebakan yang sering ketemu

TL;DR: htmx memicu event DOM di tiap langkah: htmx:beforeRequest sebelum request dikirim (bisa dibatalkan dengan event.preventDefault()), htmx:afterSwap sesudah balasan ditukar, lalu htmx:afterRequest, dan htmx:responseError untuk 4xx atau 5xx. Request event dikirim ke elemen pengirim, swap event ke target. Dengarkan lewat hx-on::after-request="..." (huruf kecil, dua titik dua) atau document.body.addEventListener('htmx:afterSwap', ...). Header balasan HX-Trigger: orderBaru memicu event buatanmu di client, dan elemen lain bisa bereaksi dengan hx-trigger="orderBaru from:body".

Yang akan kamu pelajari