# Referensi Cepat htmx

*Atribut, trigger, swap, event, extension*

> Source: htmx Documentation (htmx.org) · MIT

## Dasar

### Instalasi

```
<script src="https://unpkg.com/htmx.org@2"></script>

<!-- Or via npm -->
npm install htmx.org
```

### Cara Kerja

| Command | Description |
|---------|-------------|
| `HTML-driven` | Kirim AJAX dari atribut HTML, tanpa JS |
| `Swap konten` | Server mengembalikan fragment HTML, htmx menukarnya |
| `Progressive` | Memperkaya HTML standar; degradasi dengan baik |
| `REST-friendly` | Bekerja dengan framework server-side apa pun |

## Atribut

### Atribut Request Utama

| Command | Description |
|---------|-------------|
| `hx-get="/url"` | Kirim request GET ke URL |
| `hx-post="/url"` | Kirim request POST ke URL |
| `hx-put="/url"` | Kirim request PUT ke URL |
| `hx-patch="/url"` | Kirim request PATCH ke URL |
| `hx-delete="/url"` | Kirim request DELETE ke URL |

### Atribut Perilaku

| Command | Description |
|---------|-------------|
| `hx-trigger` | Event yang memicu request |
| `hx-target` | Elemen tujuan penukaran konten |
| `hx-swap` | Cara menukar konten respons |
| `hx-select` | Pilih subset dari HTML respons |
| `hx-vals` | Tambahkan nilai ekstra ke request |
| `hx-confirm` | Tampilkan dialog konfirmasi sebelum request |
| `hx-disable` | Nonaktifkan pemrosesan htmx pada elemen |

## Trigger

### Sintaks Trigger

```
<!-- Default: natural event (click for buttons) -->
<button hx-get="/data">Load</button>

<!-- Custom trigger event -->
<div hx-get="/news" hx-trigger="every 5s">Feed</div>

<!-- Multiple triggers -->
<input hx-get="/search" hx-trigger="keyup changed delay:300ms" />
```

### Modifier Trigger

| Command | Description |
|---------|-------------|
| `changed` | Hanya picu jika nilai berubah |
| `delay:Ns` | Tunggu N detik sebelum picu |
| `throttle:Nms` | Batasi satu kali per N ms |
| `once` | Picu hanya satu kali |
| `from:selector` | Dengarkan di elemen berbeda |
| `every Ns` | Poll setiap N detik |
| `load` | Picu saat elemen dimuat |
| `revealed` | Picu saat elemen terlihat di layar |

## Target

### Pemilihan Target

```
<!-- Target another element -->
<button hx-get="/data" hx-target="#result">Load</button>
<div id="result"></div>

<!-- Target closest ancestor -->
<button hx-get="/row" hx-target="closest tr">Update</button>

<!-- Target with CSS selector -->
<button hx-get="/info" hx-target="next .output">Go</button>
```

### Kata Kunci Target

| Command | Description |
|---------|-------------|
| `this` | Elemen itu sendiri (default) |
| `closest <sel>` | Ancestor terdekat yang cocok dengan selector |
| `find <sel>` | Keturunan pertama yang cocok dengan selector |
| `next <sel>` | Sibling berikutnya yang cocok dengan selector |
| `previous <sel>` | Sibling sebelumnya yang cocok dengan selector |

## Swapping

### Strategi Swap

| Command | Description |
|---------|-------------|
| `innerHTML` | Ganti konten dalam (default) |
| `outerHTML` | Ganti seluruh elemen target |
| `afterbegin` | Tambahkan di awal dalam target |
| `beforeend` | Tambahkan di akhir dalam target |
| `beforebegin` | Sisipkan sebelum target |
| `afterend` | Sisipkan setelah target |
| `delete` | Hapus elemen target |
| `none` | Tidak ada swap, hanya picu event |

### Modifier Swap

```
<!-- Swap with transition delay -->
<div hx-get="/data" hx-swap="innerHTML swap:300ms">

<!-- Settle delay for CSS transitions -->
<div hx-get="/data" hx-swap="innerHTML settle:500ms">

<!-- Scroll to top after swap -->
<div hx-get="/page" hx-swap="innerHTML scroll:top">
```

## Header

### Header Request (dikirim oleh htmx)

| Command | Description |
|---------|-------------|
| `HX-Request` | Selalu "true" untuk request htmx |
| `HX-Target` | ID elemen target |
| `HX-Trigger` | ID elemen yang memicu |
| `HX-Trigger-Name` | Nama elemen yang memicu |
| `HX-Current-URL` | URL saat ini di browser |
| `HX-Prompt` | Respons pengguna dari hx-prompt |

### Header Response (dikirim oleh server)

| Command | Description |
|---------|-------------|
| `HX-Redirect` | Redirect sisi client ke URL |
| `HX-Refresh` | Refresh halaman penuh jika "true" |
| `HX-Retarget` | Ganti hx-target dengan CSS selector |
| `HX-Reswap` | Ganti strategi hx-swap |
| `HX-Trigger` | Picu event sisi client |
| `HX-Push-Url` | Push URL ke history browser |

## Event

### Event Siklus Hidup

| Command | Description |
|---------|-------------|
| `htmx:configRequest` | Sebelum request; ubah params/header |
| `htmx:beforeRequest` | Tepat sebelum panggilan AJAX |
| `htmx:afterRequest` | Setelah request selesai |
| `htmx:beforeSwap` | Sebelum konten ditukar |
| `htmx:afterSwap` | Setelah konten ditukar |
| `htmx:afterSettle` | Setelah DOM stabil dari swap |
| `htmx:responseError` | Server mengembalikan status error |

### Mendengarkan Event

```
document.body.addEventListener("htmx:afterSwap", (e) => {
  console.log("Swapped:", e.detail.target);
});

// Cancel a request
document.body.addEventListener("htmx:configRequest", (e) => {
  if (!confirm("Proceed?")) e.preventDefault();
});
```

## Extension

### Menggunakan Extension

```
<script src="https://unpkg.com/htmx-ext-json-enc"></script>

<div hx-ext="json-enc">
  <form hx-post="/api/data">
    <input name="title" />
    <button>Submit as JSON</button>
  </form>
</div>
```

### Extension Populer

| Command | Description |
|---------|-------------|
| `json-enc` | Encode body request sebagai JSON |
| `loading-states` | Kelola class CSS loading state |
| `head-support` | Gabungkan tag <head> dari respons |
| `preload` | Preload link saat mousedown/hover |
| `sse` | Dukungan Server-Sent Events |
| `ws` | Dukungan WebSocket |
| `response-targets` | Target berbeda untuk respons error |

## Indikator

### Indikator Loading

```
<button hx-get="/slow" hx-indicator="#spinner">
  Load Data
</button>
<span id="spinner" class="htmx-indicator">Loading...</span>
```

### CSS Indikator

```
.htmx-indicator { display: none; }
.htmx-request .htmx-indicator { display: inline; }
.htmx-request.htmx-indicator { display: inline; }
```

*htmx menambahkan class htmx-request ke elemen selama request*

### Nonaktifkan Selama Request

```
<button hx-post="/submit" hx-disabled-elt="this">
  Submit
</button>
```

*hx-disabled-elt menambahkan atribut disabled selama request*

## Pola Umum

### Pencarian Aktif

```
<input type="search" name="q"
  hx-get="/search"
  hx-trigger="keyup changed delay:300ms"
  hx-target="#results" />
<div id="results"></div>
```

### Infinite Scroll

```
<tr hx-get="/rows?page=2"
    hx-trigger="revealed"
    hx-swap="afterend">
  <td>Loading more...</td>
</tr>
```

### Hapus dengan Konfirmasi

```
<button hx-delete="/item/42"
        hx-confirm="Hapus item ini?"
        hx-target="closest .item"
        hx-swap="outerHTML">
  Hapus
</button>
```

### Edit Inline

```
<div hx-get="/edit/1" hx-trigger="click"
     hx-swap="outerHTML">
  Klik untuk mengubah teks ini
</div>
```
