Indikator loading adalah elemen, misalnya tulisan "Menyimpan..." atau spinner, yang cuma terlihat selama request berjalan. htmx mengaturnya lewat satu class: selama request berjalan, htmx-request dipasang, dan begitu balasan tiba, class itu dilepas. Bayangin meja Laundry Bu Rini. Selama dia mencatat order di buku, dia membalik papan kecil bertuliskan "Sebentar, sedang dicatat", dan bel Terima dia tutup supaya gak ada yang memencetnya dua kali. Papan kecil itu hx-indicator, menutup bel itu hx-disabled-elt.
🧪 Tebakan cepat: Server butuh 1 detik untuk mencatat order. Kasir mengklik Terima cucian dua kali dengan cepat, dan form-nya gak punya
hx-disabled-elt. Berapa order Bu Tini yang tercatat? Jawabannya ada di bagian "hx-disabled-elt: cegah klik dua kali".
Class htmx-request dan CSS bawaan htmx
Saat htmx mulai mengirim request, elemen pengirimnya diberi class htmx-request. Saat balasan tiba, class itu dilepas. htmx juga menambahkan CSS ini ke <head> halamanmu secara otomatis:
.htmx-indicator { opacity: 0; visibility: hidden; }
.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator { opacity: 1; visibility: visible; transition: opacity 200ms ease-in; }
- Elemen ber-class
htmx-indicatortersembunyi. - Ia muncul (memudar masuk 200 ms) kalau induknya, atau dirinya sendiri, sedang memakai
htmx-request.
Jadi spinner di dalam tombol langsung jalan, tanpa atribut tambahan:
<button hx-get="/order/12/status" hx-target="#status-12">
Cek status <span class="htmx-indicator">memuat...</span>
</button>
Tombolnya diberi htmx-request, dan <span> di dalamnya ikut muncul.
hx-indicator: tunjuk penandanya
Tulisan "Menyimpan..." di meja Bu Rini ada di luar form. Form-nya menunjuk tulisan itu:
<form id="terima" hx-post="/order" hx-target="#nota" hx-indicator="#memuat">
<input name="nama">
<input name="berat">
<button>Terima cucian</button>
</form>
<span id="memuat" class="htmx-indicator">Menyimpan...</span>
<div id="nota"></div>
hx-indicator="#memuat": classhtmx-requestdipasang di#memuatsendiri, bukan di form. Aturan kedua di CSS bawaan (.htmx-request.htmx-indicator) yang memunculkannya.- Isinya selector CSS (pakai
#untuk id), atau kata kunci relatif seperticlosest formdanfind .spinner.
Dengan server yang membalas dalam 1 detik:
| Waktu | Class #memuat |
Yang terlihat |
|---|---|---|
| sebelum diklik | htmx-indicator |
tersembunyi |
| 0 ms, Terima ditekan | htmx-indicator htmx-request |
"Menyimpan..." muncul |
| 1.000 ms, balasan tiba | htmx-indicator |
"Menyimpan..." hilang, nota muncul di #nota |
hx-disabled-elt: cegah klik dua kali
htmx gak membuang klik kedua yang datang saat request pertama masih berjalan. Ia menahannya, lalu mengirimnya begitu balasan pertama tiba. Jadi klik dua kali mengirim 2 POST, dan server mencatat order #15 dan #16 untuk Bu Tini yang sama. Itu jawaban tebakannya. Klik tiga kali pun tetap 2, karena htmx cuma menyimpan satu antrean, yang terakhir.
<form id="terima" hx-post="/order" hx-target="#nota"
hx-indicator="#memuat" hx-disabled-elt="find button">
hx-disabled-elt="find button": selama request berjalan,<button>di dalam form diberi atributdisabled. Tombol yang disabled gak bisa diklik, dan Enter di kotak isian juga gak mengirim form. Hasilnya cuma order #15.- Begitu balasan tiba, htmx melepas lagi
disabledyang dia pasang. - Nilainya selector CSS,
this, atau kata kunci sepertifind,closest,next,previous. Boleh beberapa, dipisah koma:find input, find button.
Menghias sendiri dengan htmx-request
Class htmx-request bisa dipakai di CSS-mu sendiri. Contoh, papan order yang polling diredupkan selama menunggu balasan:
#papan-order.htmx-request { opacity: 0.5; }
Di komputermu sendiri server biasanya membalas dalam beberapa milidetik, jadi penandanya cuma berkedip. Untuk mencobanya, pilih "Slow 3G" di tab Network DevTools.
⚠️ Jebakan yang sering ketemu
- Class salah ketik atau gak ada. Tanpa class persis
htmx-indicator, CSS bawaan gak menyembunyikannya, jadi "Loading..." terlihat terus. Di latihan,<span id="spinner">harus ber-class persishtmx-indicator, dan tombolhx-get="/api/data"-nya harus punyahx-indicator="#spinner". - Spinner di luar elemen pemicu tanpa
hx-indicator.htmx-requestdipasang di tombolnya, dan spinner yang bukan isinya gak ikut muncul. - Lupa tanda
#.hx-indicator="memuat"mencari tag<memuat>. Gak ketemu, jadi gak ada yang muncul. Request-nya tetap terkirim, dan error-nya cuma ada di Console. - Gak ada
hx-disabled-eltdi form yang mengubah data. Klik dua kali mencatat dua order.
TL;DR: Selama request berjalan, htmx memasang class htmx-request di elemen pengirimnya, atau di elemen yang ditunjuk hx-indicator="#memuat". CSS bawaan htmx menyembunyikan .htmx-indicator dan memunculkannya saat dia atau induknya memakai htmx-request. Jadi spinner di dalam tombol cukup diberi class htmx-indicator, dan spinner di tempat lain ditunjuk dengan hx-indicator (pakai #). hx-disabled-elt="find button" memasang disabled selama request, supaya klik kedua gak mengirim order kedua. Tanpa itu, klik kedua ditahan lalu tetap dikirim.