# Référence rapide htmx

*Attributs, déclencheurs, échange, événements, extensions*

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

## Bases

### Installation

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

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

### Comment ça fonctionne

| Command | Description |
|---------|-------------|
| `HTML-driven` | Émettre des requêtes AJAX depuis des attributs HTML, sans JS |
| `Swap content` | Le serveur retourne des fragments HTML, htmx les insère |
| `Progressive` | Améliore le HTML standard ; se dégrade gracieusement |
| `REST-friendly` | Fonctionne avec tout framework côté serveur |

## Attributs

### Attributs de requête principaux

| Command | Description |
|---------|-------------|
| `hx-get="/url"` | Émettre une requête GET vers l'URL |
| `hx-post="/url"` | Émettre une requête POST vers l'URL |
| `hx-put="/url"` | Émettre une requête PUT vers l'URL |
| `hx-patch="/url"` | Émettre une requête PATCH vers l'URL |
| `hx-delete="/url"` | Émettre une requête DELETE vers l'URL |

### Attributs de comportement

| Command | Description |
|---------|-------------|
| `hx-trigger` | Événement qui déclenche la requête |
| `hx-target` | Élément dans lequel insérer le contenu |
| `hx-swap` | Comment échanger le contenu de la réponse |
| `hx-select` | Sélectionner un sous-ensemble du HTML de la réponse |
| `hx-vals` | Ajouter des valeurs supplémentaires à la requête |
| `hx-confirm` | Afficher une boîte de confirmation avant la requête |
| `hx-disable` | Désactiver le traitement htmx sur l'élément |

## Déclencheurs

### Syntaxe des déclencheurs

```
<!-- Par défaut : événement naturel (click pour les boutons) -->
<button hx-get="/data">Load</button>

<!-- Événement déclencheur personnalisé -->
<div hx-get="/news" hx-trigger="every 5s">Feed</div>

<!-- Déclencheurs multiples -->
<input hx-get="/search" hx-trigger="keyup changed delay:300ms" />
```

### Modificateurs de déclencheur

| Command | Description |
|---------|-------------|
| `changed` | Ne se déclenche que si la valeur a changé |
| `delay:Ns` | Attendre N secondes avant de se déclencher |
| `throttle:Nms` | Limiter à une fois par N ms |
| `once` | Se déclencher uniquement la première fois |
| `from:selector` | Écouter sur un élément différent |
| `every Ns` | Interroger toutes les N secondes |
| `load` | Se déclencher au chargement de l'élément |
| `revealed` | Se déclencher quand l'élément entre dans la vue |

## Cibles

### Sélection de la cible

```
<!-- Cibler un autre élément -->
<button hx-get="/data" hx-target="#result">Load</button>
<div id="result"></div>

<!-- Cibler l'ancêtre le plus proche -->
<button hx-get="/row" hx-target="closest tr">Update</button>

<!-- Cibler avec un sélecteur CSS -->
<button hx-get="/info" hx-target="next .output">Go</button>
```

### Mots-clés de cible

| Command | Description |
|---------|-------------|
| `this` | L'élément lui-même (par défaut) |
| `closest <sel>` | Ancêtre le plus proche correspondant au sélecteur |
| `find <sel>` | Premier descendant correspondant au sélecteur |
| `next <sel>` | Frère suivant correspondant au sélecteur |
| `previous <sel>` | Frère précédent correspondant au sélecteur |

## Échange

### Stratégies d'échange

| Command | Description |
|---------|-------------|
| `innerHTML` | Remplacer le contenu interne (par défaut) |
| `outerHTML` | Remplacer l'élément cible entier |
| `afterbegin` | Insérer en tête de la cible |
| `beforeend` | Insérer en fin de la cible |
| `beforebegin` | Insérer avant la cible |
| `afterend` | Insérer après la cible |
| `delete` | Supprimer l'élément cible |
| `none` | Pas d'échange, déclencher uniquement les événements |

### Modificateurs d'échange

```
<!-- Échange avec délai de transition -->
<div hx-get="/data" hx-swap="innerHTML swap:300ms">

<!-- Délai de stabilisation pour les transitions CSS -->
<div hx-get="/data" hx-swap="innerHTML settle:500ms">

<!-- Défiler vers le haut après l'échange -->
<div hx-get="/page" hx-swap="innerHTML scroll:top">
```

## En-têtes

### En-têtes de requête (envoyés par htmx)

| Command | Description |
|---------|-------------|
| `HX-Request` | Toujours "true" pour les requêtes htmx |
| `HX-Target` | ID de l'élément cible |
| `HX-Trigger` | ID de l'élément déclencheur |
| `HX-Trigger-Name` | Nom de l'élément déclencheur |
| `HX-Current-URL` | URL actuelle du navigateur |
| `HX-Prompt` | Réponse de l'utilisateur depuis hx-prompt |

### En-têtes de réponse (envoyés par le serveur)

| Command | Description |
|---------|-------------|
| `HX-Redirect` | Redirection côté client vers l'URL |
| `HX-Refresh` | Actualisation complète de la page si "true" |
| `HX-Retarget` | Remplacer hx-target par un sélecteur CSS |
| `HX-Reswap` | Remplacer la stratégie hx-swap |
| `HX-Trigger` | Déclencher des événements côté client |
| `HX-Push-Url` | Pousser l'URL dans l'historique du navigateur |

## Événements

### Événements du cycle de vie

| Command | Description |
|---------|-------------|
| `htmx:configRequest` | Avant la requête ; modifier les paramètres/en-têtes |
| `htmx:beforeRequest` | Juste avant l'appel AJAX |
| `htmx:afterRequest` | Après la fin de la requête |
| `htmx:beforeSwap` | Avant l'insertion du contenu |
| `htmx:afterSwap` | Après l'insertion du contenu |
| `htmx:afterSettle` | Après la stabilisation du DOM |
| `htmx:responseError` | Le serveur a retourné un statut d'erreur |

### Écouter les événements

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

// Annuler une requête
document.body.addEventListener("htmx:configRequest", (e) => {
  if (!confirm("Proceed?")) e.preventDefault();
});
```

## Extensions

### Utiliser les extensions

```
<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>
```

### Extensions populaires

| Command | Description |
|---------|-------------|
| `json-enc` | Encoder le corps de la requête en JSON |
| `loading-states` | Gérer les classes CSS d'état de chargement |
| `head-support` | Fusionner les balises <head> des réponses |
| `preload` | Précharger les liens au mousedown/hover |
| `sse` | Support des Server-Sent Events |
| `ws` | Support WebSocket |
| `response-targets` | Cibles différentes pour les réponses d'erreur |

## Indicateurs

### Indicateur de chargement

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

### CSS de l'indicateur

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

*htmx ajoute la classe htmx-request à l'élément pendant les requêtes*

### Désactiver pendant la requête

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

*hx-disabled-elt ajoute l'attribut disabled pendant la requête*

## Modèles courants

### Recherche active

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

### Défilement infini

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

### Suppression avec confirmation

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

### Édition en ligne

```
<div hx-get="/edit/1" hx-trigger="click"
     hx-swap="outerHTML">
  Click to edit this text
</div>
```
