hx-select — HTMX

hx-select memungkinkan kamu memilih bagian tertentu dari response HTML. Memilih Fragment Load Content Server mengembalikan halaman penuh, tapi HTMX hanya…

hx-select memilih sebagian dari balasan HTML dengan selector CSS, sebelum balasan itu ditaruh di target. Ini berguna saat server membalas halaman penuh, padahal kamu cuma butuh satu bagiannya. Bayangin Bu Rini meminta fotokopi halaman buku order dari cabang lain. Yang datang satu halaman penuh: kop toko, alamat, iklan, dan tabel order. Dia cuma butuh tabelnya, jadi tabel itu digunting lalu ditempel di papan. Guntingnya hx-select. Fotokopinya tetap satu halaman penuh: menggunting gak membuat kiriman jadi lebih tipis.

🧪 Tebakan cepat: Tombol Muat ulang papan punya hx-get="/papan" hx-target="#papan-order" hx-select="#papan-order", tanpa hx-swap. Server membalas halaman /papan penuh. Sesudah diklik, ada berapa elemen ber-id papan-order di halaman? Jawabannya ada di bagian "Pasangan yang benar".

Masalahnya: server membalas halaman penuh

Route lama Bu Rini membalas GET /papan dengan halaman yang sama seperti saat dibuka:

<!doctype html>
<html lang="id">
<head><title>Papan order | Laundry Bu Rini</title> ...</head>
<body>
<header><h1>Laundry Bu Rini</h1><nav>...</nav></header>
<main id="isi">
  <div id="ringkasan"><p>4 order aktif, 1 siap diambil</p></div>
  <ul id="papan-order">
    <li id="order-12">#12 Pak Darto, 3 kg: <span>Disetrika</span></li>
    ...
    <li id="order-15">#15 Bu Tini, 4 kg: <span>Antre</span></li>
  </ul>
  <button id="muat-ulang" ...>Muat ulang papan</button>
</main>
<footer>Jl. Melati 5</footer>
</body>
</html>

Tanpa hx-select, htmx membuang <head>-nya lalu menaruh seluruh isi <body> di target. Header, menu, ringkasan, tombol, dan footer muncul di dalam papan order. Judul tab juga ikut diganti <title> dari balasan.

hx-select: ambil bagian yang kamu mau

<button id="muat-ulang" hx-get="/papan" hx-target="#papan-order"
        hx-select="#papan-order > li">
  Muat ulang papan
</button>

Pasangan yang benar

hx-select hx-swap Hasil di halaman
(gak ada) innerHTML seluruh <body> balasan di dalam papan
#papan-order innerHTML <ul> baru di dalam <ul> lama: 2 elemen ber-id papan-order
#papan-order outerHTML <ul> lama ditukar <ul> baru: 1 papan, 4 order
#papan-order > li innerHTML isi papan ditukar 4 <li> baru: 1 papan, 4 order

hx-select="#papan-order" memilih seluruh <ul>. Bawaan innerHTML menaruhnya di dalam <ul> yang lama, jadi ada 2 elemen ber-id papan-order, ul di dalam ul. Itu jawaban tebakannya. Kalau yang dipilih elemen yang sama dengan target, pakai outerHTML. Kalau mau tetap innerHTML, pilih isinya: #papan-order > li.

Yang gak berubah: ukuran balasan

hx-select menyaring sesudah balasan tiba. Di Lab, server tetap mengirim halaman penuh, 961 byte, walau yang dipakai cuma papan 310 byte. Jadi hx-select itu kemudahan, bukan penghematan. Untuk balasan yang benar-benar kecil, server membaca header HX-Request: true lalu membalas potongan papannya saja. Di Laravel: if ($request->header('HX-Request')) { return view('papan._order', ...); }.

hx-select-oob: ambil satu bagian lagi

<button id="muat-ulang" hx-get="/papan" hx-target="#papan-order"
        hx-select="#papan-order" hx-swap="outerHTML"
        hx-select-oob="#ringkasan">

#ringkasan dari balasan yang sama ikut menggantikan #ringkasan di halaman, dicocokkan lewat id-nya. Jadi satu request memperbarui papan dan ringkasan sekaligus. Swap out of band (OOB) dibahas lebih dalam di pelajaran OOB swaps.

⚠️ Jebakan yang sering ketemu

TL;DR: hx-select="#papan-order" mengambil bagian yang cocok dari balasan, semua yang cocok, sebelum ditaruh di target. Berguna saat server membalas halaman penuh. Kalau yang dipilih elemen yang sama dengan target, pakai hx-swap="outerHTML" (atau pilih isinya, #papan-order > li), supaya gak jadi ul di dalam ul. Selector yang gak cocok mengosongkan target tanpa error, dan hx-select diwariskan ke elemen di dalamnya. hx-select-oob="#ringkasan" mengambil satu bagian lagi berdasarkan id. Ukuran balasan gak berubah: untuk balasan kecil, server membalas potongan saat ada HX-Request: true.

Yang akan kamu pelajari