hx-swap menentukan cara balasan HTML ditaruh di target: mengganti isinya, mengganti elemennya sendiri, menambah di awal atau di akhir, menyisipkan di luar elemen, atau menghapusnya. hx-target menjawab "di mana", hx-swap menjawab "bagaimana". Bayangin papan order di Laundry Bu Rini lagi. Kadang dia cuma mengganti tulisan di satu kartu, kadang mencabut kartunya dan memasang kartu baru, kadang menempel kartu order baru di bawah, dan kadang mencabut kartu yang cuciannya sudah diambil. Papannya sama, caranya beda.
🧪 Tebakan cepat: Papan
<ul id="papan-order">berisi 3 order. Form Terima cucian mengirim order baru denganhx-target="#papan-order"dan tanpahx-swap. Server membalas satu<li>order baru. Sesudah form dikirim, ada berapa order di papan? Jawabannya ada di bagian "innerHTML: bawaannya, dan kenapa bikin kaget".
Delapan cara menaruh balasan
Posisinya terhadap target <ul id="papan-order">:
<!-- beforebegin: sebelum <ul> -->
<ul id="papan-order">
<!-- afterbegin: di awal isinya -->
<li id="order-12">#12 Pak Darto, 3 kg: <span>Dicuci</span></li>
<li id="order-13">#13 Mbak Wulan, 2 kg: <span>Disetrika</span></li>
<li id="order-14">#14 Mas Yoga, 5 kg: <span>Siap diambil</span></li>
<!-- beforeend: di akhir isinya -->
</ul>
<!-- afterend: sesudah </ul> -->
hx-swap |
Yang terjadi pada target |
|---|---|
innerHTML |
isinya diganti balasan (bawaan, kalau hx-swap gak ditulis) |
outerHTML |
elemen target sendiri diganti balasan |
afterbegin |
balasan ditambah di awal isinya, sebelum isi pertama |
beforeend |
balasan ditambah di akhir isinya, sesudah isi terakhir |
beforebegin |
balasan disisipkan tepat sebelum target, di luarnya |
afterend |
balasan disisipkan tepat sesudah target, di luarnya |
delete |
target dihapus, isi balasannya diabaikan |
none |
request tetap dikirim, tapi halamannya gak berubah |
Ada juga textContent, yang menaruh balasan sebagai teks biasa, jadi tag-nya tampil apa adanya.
innerHTML: bawaannya, dan kenapa bikin kaget
<form hx-post="/order" hx-target="#papan-order">
<input name="nama" value="Bu Tini">
<input name="berat" value="4">
<button>Terima cucian</button>
</form>
Server membalas <li id="order-15">#15 Bu Tini, 4 kg: <span>Antre</span></li>. Tanpa hx-swap, htmx memakai innerHTML: seluruh isi <ul> diganti balasan. Papannya tinggal 1 order, #15, dan tiga order lama hilang. Itu jawaban tebakannya. innerHTML cocok untuk kotak yang isinya memang diganti utuh, misalnya ringkasan atau hasil cari.
beforeend: tambah di akhir daftar
<form hx-post="/order" hx-target="#papan-order" hx-swap="beforeend">
- Order #15 masuk sesudah #14, dan ketiga order lama tetap. Papan sekarang 4 order.
afterbeginkebalikannya: #15 masuk paling atas, sebelum #12. Cocok untuk daftar yang terbaru di atas, misalnya notifikasi.beforebegindanafterendmenaruh balasan di luar<ul>, jadi<li>-nya gak masuk daftar. Untuk menambah item, yang benarbeforeendatauafterbegin.
outerHTML: ganti elemennya sendiri
<li id="order-12">#12 Pak Darto, 3 kg: <span>Disetrika</span>
<button hx-post="/order/12/siap" hx-target="closest li" hx-swap="outerHTML">
Tandai siap
</button>
</li>
- Server membalas kartu baru yang lengkap:
<li id="order-12">#12 Pak Darto, 3 kg: <span>Siap diambil</span></li>. Seluruh<li>lama, termasuk tombolnya, diganti kartu ini. - Balasannya harus membawa
id="order-12"lagi. Kalau gak, elemen ber-id itu hilang, dan request berikutnya yang menargetkan#order-12gak dikirim. - Tanpa
hx-target, target-nya elemen itu sendiri, jadi<button hx-get="..." hx-swap="outerHTML">menukar tombol itu dengan balasannya, bukan cuma tulisannya. - Hati-hati dengan
outerHTMLpada<ul id="papan-order">: daftarnya diganti satu<li>, dan idpapan-orderikut hilang.
delete dan none
hx-swap="delete"menghapus target, apa pun isi balasannya. Contoh:<button hx-delete="/order/14" hx-target="closest li" hx-swap="delete">Sudah diambil</button>mencabut kartu #14 dari papan.hx-swap="none"mengirim request tapi gak mengubah halaman. Contoh: tombol "Kirim pengingat WA" yang cuma menyuruh server mengirim pesan.
Modifier: menunda dan menggulir
Sesudah nama cara, kamu bisa menambah modifier, dipisah spasi:
<button hx-delete="/order/14" hx-target="closest li" hx-swap="delete swap:1s">
Sudah diambil
</button>
<style>
li.htmx-swapping { opacity: 0; transition: opacity 1s ease-out; }
</style>
swap:1smenunda swap 1 detik. Selama menunggu, target memakai classhtmx-swapping, jadi CSS di atas memudarkan kartunya dulu, baru kartunya dihapus.settle:200msmengatur jeda settle (bawaannya 20 ms). Selama settle, elemen yang baru masuk memakai classhtmx-added, dan bisa diberi animasi muncul.scroll:topmenggulir target ke atasnya sesudah swap,show:topmenggulir halaman supaya target kelihatan.
⚠️ Jebakan yang sering ketemu
- Lupa
hx-swap="beforeend"saat menambah item. BawaannyainnerHTML, jadi daftar lama terhapus. Di latihan, tombolTambah Itemharus punyahx-swap="beforeend"supayaItem awaltetap ada. - Salah ketik nilainya.
hx-swap="append"gak dikenal htmx, dan nilai yang gak dikenal diam-diam jadiinnerHTML. Gak ada error yang tampil. - Balasan
outerHTMLtanpa id. Elemen yang ditukar kehilangan id-nya, jadi target berikutnya gak ketemu. - Mengira
outerHTMLcuma mengganti tulisan. ItuinnerHTML.outerHTMLmengganti seluruh elemen, tag-nya juga.
TL;DR: hx-swap mengatur cara balasan ditaruh di target. Bawaannya innerHTML (isi diganti), jadi daftar terhapus kalau kamu lupa menulis hx-swap. outerHTML mengganti elemennya sendiri (balasannya harus membawa id-nya lagi), beforeend dan afterbegin menambah di akhir atau awal isi, beforebegin dan afterend di luar elemen, delete menghapus target, none gak mengubah halaman. Modifier seperti swap:1s (target memakai htmx-swapping selama menunggu), settle:200ms, dan scroll:top ditulis sesudah nama caranya. Nilai yang salah ketik diam-diam jadi innerHTML.