hx-trigger menentukan kapan sebuah elemen mengirim request: event apa yang ditunggu, plus aturan tambahan seperti "tunggu dulu", "paling sering sekali per 2 detik", atau "cuma sekali". Bayangin kasir Laundry Bu Rini mencari nama pelanggan di buku order. Kalau dia membalik buku setiap kali pelanggan menyebut satu huruf ("D... a... r..."), dia kerja lima kali untuk satu nama. Kasir yang pintar menunggu pelanggan diam setengah detik, baru mencari. Papan order di dinding juga dicek ulang tiap 30 detik, tanpa ada yang menyuruh. Keduanya diatur hx-trigger.
🧪 Tebakan cepat: Kolom cari di papan punya
hx-trigger="keyup". Kamu mengetikdarto, 5 huruf. Berapa request yang dikirim ke/cari? Jawabannya ada di bagian "Mencari sambil mengetik: keyup".
Bawaan, dan cara menggantinya
Dari pelajaran hx-get: <input> menunggu change (nilainya berubah lalu kamu pindah kotak atau menekan Enter), <form> menunggu submit, elemen lain menunggu click. hx-trigger mengganti bawaan itu:
<input name="cari" type="search" hx-get="/cari" hx-trigger="keyup" hx-target="#hasil">
- Isinya nama event DOM apa pun:
click,keyup,input,change,mouseenter,submit. - htmx juga punya event sendiri:
load,revealed,intersect, daneveryuntuk polling. - Sesudah nama event, tambahkan modifier dipisah spasi:
keyup changed delay:500ms. - Beberapa pemicu dipisah koma:
load, every 30s.
Mencari sambil mengetik: keyup
Dengan hx-trigger="keyup", setiap tombol keyboard yang dilepas mengirim request:
| Kamu mengetik | Nilai kolom | Request |
|---|---|---|
| d | d |
GET /cari?cari=d |
| a | da |
GET /cari?cari=da |
| r | dar |
GET /cari?cari=dar |
| t | dart |
GET /cari?cari=dart |
| o | darto |
GET /cari?cari=darto |
5 huruf, 5 request. Itu jawaban tebakannya. Empat yang pertama gak berguna, dan menekan Shift atau panah kiri juga mengirim request lagi, padahal nilainya sama.
Debounce: delay dan changed
<input name="cari" type="search" hx-get="/cari"
hx-trigger="keyup changed delay:500ms" hx-target="#hasil">
delay:500ms: tiapkeyupmemulai hitungan 500 ms. Kalau adakeyupbaru sebelum habis, hitungannya diulang dari nol. Request baru dikirim 500 ms sesudah tombol terakhir. Teknik ini namanya debounce.changed: event cuma dihitung kalau nilainya beda dari terakhir kali. Shift, panah, atau Ctrl gak mengubah nilai, jadi diabaikan dan gak mengulang hitungan.- Satuannya
msataus:delay:1ssama dengandelay:1000ms.
Mengetik darto dengan jeda 120 ms per huruf:
| Waktu | Kejadian |
|---|---|
| 0 ms | d, hitungan 500 ms mulai |
| 120, 240, 360 ms | a, r, t, hitungannya diulang tiap kali |
| 480 ms | o, hitungan terakhir mulai |
| 980 ms | GET /cari?cari=darto, satu-satunya request |
| 1.400 ms | Shift dilepas, nilai tetap darto, diabaikan |
input changed delay:500ms bekerja sama, dan ikut menangkap teks yang di-paste lewat klik kanan.
throttle: paling sering sekali per jangka waktu
<button hx-get="/order/12/status" hx-trigger="click throttle:2s" hx-target="#status-12">
Cek status
</button>
Klik pertama langsung mengirim request. Klik lain dalam 2 detik sesudahnya dibuang, bukan ditunda. Cocok untuk tombol yang suka diklik berkali-kali. Untuk pencarian, throttle salah pilih: mengetik darto dalam 2 detik cuma mengirim cari=d, dan darto gak pernah terkirim.
Polling: every
<ul id="papan-order" hx-get="/order" hx-trigger="every 30s">
<li id="order-12">#12 Pak Darto, 3 kg: <span>Dicuci</span></li>
...
</ul>
every 30smengirimGET /ordertiap 30 detik, dan balasannya (baris-baris<li>terbaru) mengganti isi papan. Status yang diubah Bu Rini di belakang ikut muncul.- Request pertama dikirim 30 detik sesudah halaman dibuka, bukan langsung. Untuk langsung juga, tulis
hx-trigger="load, every 30s". - Polling berhenti sendiri kalau elemennya dihapus dari halaman.
- Hitung biayanya: satu tab terbuka = 120 request per jam. Sepuluh tab = 1.200.
from: dan once
<button id="muat-ulang">Muat ulang</button>
<ul id="papan-order" hx-get="/order" hx-trigger="every 30s, click from:#muat-ulang">...</ul>
<li id="order-12" hx-get="/order/12/riwayat" hx-trigger="mouseenter once">...</li>
from:#muat-ulang: papan mendengarkan klik di tombol lain. Klik di papannya sendiri gak memicu apa-apa lagi, karenaclickbawaannya sudah diganti. Selain selector CSS,from:menerimadocument,window,closest ..., danfind ....once: request cuma dikirim pada event pertama. Kursor masuk kartu #12 kedua kalinya gak mengirim apa-apa.
load, revealed, intersect
load: sekali, begitu elemen dimuat. Dipakai kotak#ringkasandi pelajaran hx-get. Bisa ditunda:load delay:1s.revealed: sekali, saat elemen pertama kali masuk layar karena di-scroll. Cocok untuk memuat bagian bawah halaman belakangan.intersect: setiap kali elemen masuk area pandang, dengan pilihanthreshold:0.5(setengahnya terlihat). Keduanya dibahas lagi di pelajaran infinite scroll.
⚠️ Jebakan yang sering ketemu
- Pemicu kosong atau salah ketik.
hx-trigger=""kembali ke bawaan, danhx-trigger="kilk"menunggu event yang gak pernah terjadi. Gak ada error. Di latihan,<input>harus punyahx-trigger="keyup changed delay:300ms"dan<div>harus punyahx-trigger="mouseenter once". keyuptanpadelay. Satu request per huruf, dan server menanggung semuanya.throttleuntuk pencarian. Ketikan terakhir dibuang. Pencarian pakaidelay.- Polling tanpa
load. Papan baru terisi 30 detik setelah halaman dibuka. - Lupa
once. Tiap kali kursor masuk, request dikirim lagi.
TL;DR: hx-trigger mengganti event bawaan (change untuk input, submit untuk form, click untuk yang lain) dengan event pilihanmu, plus modifier dipisah spasi. keyup changed delay:500ms mengirim satu request 500 ms sesudah ketikan terakhir, dan hanya kalau nilainya berubah. throttle:2s mengirim langsung lalu membuang event berikutnya selama 2 detik. every 30s polling tiap 30 detik, mulai 30 detik setelah halaman dibuka (load, every 30s untuk langsung). from:#muat-ulang mendengar elemen lain, once cuma sekali, load saat dimuat, revealed dan intersect saat terlihat di layar. Pemicu yang salah ketik gak memicu apa pun, tanpa error.