AJAX
Le cœur de htmx est un ensemble d’attributs qui vous permettent d’émettre des requêtes AJAX directement depuis HTML :
Attribut | Description |
---|---|
hx-get | Émet une requête GET à l’URL donnée |
hx-post | Émet une requête POST à l’URL donnée |
hx-put | Émet une requête PUT à l’URL donnée |
hx-patch | Émet une requête PATCH à l’URL donnée |
hx-delete | Émet une requête DELETE à l’URL donnée |
Chacun de ces attributs prend une URL pour émettre une requête AJAX. L’élément émettra une requête du type spécifié à l’URL donnée lorsque l’élément sera déclenché :
Cela indique au navigateur :
Lorsqu’un utilisateur clique sur ce bouton, émettez une requête PUT vers l’URL
/messages
et chargez la réponse dans le bouton.
Déclencher des Requêtes
Par défaut, les requêtes AJAX sont déclenchées par l’événement « naturel » d’un élément :
input
,textarea
etselect
sont déclenchés sur l’événementchange
.form
est déclenché sur l’événementsubmit
.- tout le reste est déclenché par l’événement
click
.
Si vous souhaitez un comportement différent, vous pouvez utiliser l’attribut hx-trigger pour spécifier quel événement déclenchera la requête.
Voici un div
qui envoie une requête POST à /mouse_entered
lorsqu’une souris entre dedans :
Modificateurs de Déclencheur
Un déclencheur peut également avoir quelques modificateurs supplémentaires qui modifient son comportement. Par exemple, si vous voulez qu’une requête ne se produise qu’une seule fois, vous pouvez utiliser le modificateur once
pour le déclencheur :
D’autres modificateurs que vous pouvez utiliser pour les déclencheurs sont :
changed
- n’émet une requête que si la valeur de l’élément a changé.delay:<intervalle de temps>
- attend le temps donné (par exemple1s
) avant d’émettre la requête. Si l’événement se déclenche à nouveau, le compte à rebours est réinitialisé.throttle:<intervalle de temps>
- attend le temps donné (par exemple1s
) avant d’émettre la requête. Contrairement àdelay
, si un
nouvel événement survient avant la fin du délai, l’événement sera ignoré, de sorte que la requête se déclenchera à la fin de la période.
from:<Sélecteur CSS>
- écoute l’événement sur un autre élément. Cela peut être utilisé pour des choses comme des raccourcis clavier. Notez que ce sélecteur CSS n’est pas réévalué si la page change.
Vous pouvez utiliser ces attributs pour implémenter de nombreux schémas UX courants, tels que Recherche Active :
Cet input émettra une requête 500 millisecondes après un événement keyup si l’input a été modifié et insère les résultats dans le div
avec l’id search-results
.
Plusieurs déclencheurs peuvent être spécifiés dans l’attribut hx-trigger, séparés par des virgules.
Filtres de Déclencheur
Vous pouvez également appliquer des filtres de déclencheur en utilisant des crochets après le nom de l’événement, englobant une expression JavaScript qui sera évaluée. Si l’expression évalue à true
, l’événement se déclenchera, sinon il ne se déclenchera pas.
Voici un exemple qui ne se déclenche que sur un clic avec contrôle de l’élément :
Les propriétés comme ctrlKey
seront résolues par rapport à l’événement déclencheur d’abord, puis par rapport à la portée globale. Le symbole this
sera défini sur l’élément actuel.
Événements Spéciaux
htmx fournit quelques événements spéciaux pour être utilisés dans hx-trigger :
load
- se déclenche une fois lorsque l’élément est d’abord chargé.revealed
- se déclenche une fois lorsqu’un élément entre pour la première fois dans le champ de vision.intersect
- se déclenche une fois lorsqu’un élément intercepte pour la première fois le champ de vision. Cela prend en charge deux options supplémentaires :root:<sélecteur>
- un sélecteur CSS de l’élément racine pour l’intersection.threshold:<flottant>
- un nombre flottant entre 0,0 et 1,0, indiquant la quantité d’intersection pour déclencher l’événement.
Vous pouvez également utiliser des événements personnalisés pour déclencher des requêtes si vous avez un cas d’utilisation avancé.
Polling
Si vous voulez qu’un élément sonde l’URL donnée plutôt que d’attendre un événement, vous pouvez utiliser la syntaxe every
avec l’attribut hx-trigger :
Cela indique à htmx :
Toutes les 2 secondes, émettez une requête GET à
/news
et chargez la réponse dans le div.
Si vous souhaitez arrêter le sondage depuis une réponse du serveur, vous pouvez répondre avec le code de réponse HTTP 286 et l’élément annulera le sondage.
Polling de Chargement
Une autre technique pouvant être utilisée pour réaliser du polling dans htmx est le « polling de chargement », où un élément spécifie un déclencheur load
avec un délai et se remplace par la réponse :
Si le point de terminaison /messages
continue de renvoyer un div configuré de cette manière, il continuera à « sonder » l’URL toutes les secondes.
Le polling de chargement peut être utile dans des situations où un sondage a un point final où le sondage se termine, comme lorsque vous montrez une barre de progression à l’utilisateur.
Indicateurs de Requête
Lorsqu’une requête AJAX est émise, il est souvent bon de faire savoir à l’utilisateur que quelque chose se passe, car le navigateur ne lui donnera aucun retour visuel. Vous pouvez accomplir cela dans htmx en utilisant la classe htmx-indicator
.
La classe htmx-indicator
est définie de manière à ce que l’opacité de tout élément ayant cette classe soit de 0 par défaut, le rendant invisible mais présent dans le DOM.
Lorsque htmx émet une requête, il ajoutera une classe htmx-request
à un élément (soit l’élément demandeur soit un autre élément, si spécifié). La classe htmx-request
fera passer un élément enfant avec la classe htmx-indicator
à une opacité de 1, révélant l’indicateur.
Ici, nous avons un bouton. Lorsqu’il est cliqué, la classe htmx-request
sera ajoutée, ce qui révélera l’élément gif spinner. (J’aime les spinners SVG ces jours-ci.)
Bien que la classe htmx-indicator
utilise l’opacité pour masquer et montrer l’indicateur de progression, si vous préférez un autre mécanisme, vous pouvez créer votre propre transition CSS ainsi :
Si vous voulez que la classe htmx-request
soit ajoutée à un autre élément, vous pouvez utiliser l’attribut hx-indicator avec un sélecteur CSS pour ce faire :
Ici, nous appelons explicitement l’indicateur par son id. Notez que nous aurions pu placer la classe sur le div
parent et avoir le même effet.
Vous pouvez également ajouter l’attribut disabled aux éléments pendant la durée d’une requête en utilisant l’attribut hx-disabled-elt.
Cibles
Si vous souhaitez que la réponse soit chargée dans un autre élément que celui qui a fait la requête, vous pouvez utiliser l’attribut hx-target, qui prend un sélecteur CSS. Revenons à notre exemple de recherche en direct :
Vous pouvez voir que les résultats de la recherche seront chargés dans le div#search-results
, plutôt que dans l’input.
Sélecteurs CSS Étendus
hx-target
, et la plupart des attributs qui acceptent un sélecteur CSS, prennent en charge une syntaxe CSS « étendue » :
- Vous pouvez utiliser le mot-clé
this
, qui indique que l’élément sur lequel l’attributhx-target
est placé est la cible. - La syntaxe
closest <Sélecteur CSS>
trouvera l’élément ancêtre le plus proche ou lui-même, qui correspond au sélecteur CSS donné (par exemple,closest tr
ciblera la ligne de tableau la plus proche de l’élément). - La syntaxe
next <Sélecteur CSS>
trouvera l’élément suivant dans le DOM correspondant au sélecteur CSS donné. - La syntaxe
previous <Sélecteur CSS>
trouvera l’élément précédent dans le DOM correspondant au sélecteur CSS donné. find <Sélecteur CSS>
trouvera le premier enfant descendant correspondant au sélecteur CSS donné (par exemple,find tr
ciblera la première ligne de tableau descendante par rapport à l’élément).
De plus, un sélecteur CSS peut être enveloppé dans les caractères <
et />
, imitant la syntaxe du littéral de requête de hyperscript.
Les cibles relatives comme celle-ci peuvent être utiles pour créer des interfaces utilisateur flexibles sans parsemer votre DOM de nombreux attributs id
.
Swapping
htmx offre plusieurs façons différentes de remplacer le HTML renvoyé dans le DOM. Par défaut, le contenu remplace le innerHTML
de l’élément cible. Vous pouvez modifier cela en utilisant l’attribut [hx-swap](https://htmx.org/attributes/hx
-swap/) avec l’une des valeurs suivantes :
Nom | Description |
---|---|
innerHTML | par défaut, insère le contenu à l’intérieur de l’élément cible |
outerHTML | remplace entièrement l’élément cible par le contenu renvoyé |
afterbegin | insère le contenu avant le premier enfant à l’intérieur de la cible |
beforebegin | insère le contenu avant la cible dans l’élément parent de la cible |
beforeend | insère le contenu après le dernier enfant à l’intérieur de la cible |
afterend | insère le contenu après la cible dans l’élément parent de la cible |
delete | supprime l’élément cible, quelle que soit la réponse |
none | n’ajoute pas de contenu provenant de la réponse (les Swaps Hors Bande et les En-têtes de Réponse seront toujours traités) |
Morphing
En plus des mécanismes de remplacement standard ci-dessus, htmx prend également en charge les swaps de type morphing
, via des extensions. Les swaps de type morphing
tentent de fusionner le nouveau contenu dans le DOM existant, plutôt que de simplement le remplacer. Ils préservent souvent mieux des éléments comme le focus, l’état vidéo, etc., en modifiant les nœuds existants sur place pendant l’opération de swap, au prix d’une utilisation accrue du processeur.
Les extensions suivantes sont disponibles pour les swaps de type morphing :
- Idiomorph - Un algorithme de morphing créé par les développeurs de htmx.
- Morphdom Swap - Basé sur morphdom, la bibliothèque de morphing DOM originale.
- Alpine-morph - Basé sur le plugin alpine morph, fonctionne bien avec alpine.js.
Transitions de Vue
La nouvelle API View Transitions expérimentale donne aux développeurs un moyen de créer une transition animée entre différents états du DOM. Elle est encore en développement actif et n’est pas disponible dans tous les navigateurs, mais htmx fournit un moyen de travailler avec cette nouvelle API qui revient au mécanisme sans transition si l’API n’est pas disponible dans un navigateur donné.
Vous pouvez expérimenter avec cette nouvelle API en utilisant les approches suivantes :
- Définissez la variable de configuration
htmx.config.globalViewTransitions
surtrue
pour utiliser des transitions pour tous les swaps. - Utilisez l’option
transition:true
dans l’attributhx-swap
. - Si un swap d’élément est sur le point d’être transitionné en raison de l’une des configurations ci-dessus, vous pouvez intercepter l’événement
htmx:beforeTransition
et appelerpreventDefault()
dessus pour annuler la transition.
Les Transitions de Vue peuvent être configurées à l’aide de CSS, comme décrit dans la documentation Chrome pour la fonctionnalité.
Vous pouvez voir un exemple de transition de vue sur la page d’exemples d’animations.
Options de Swap
L’attribut hx-swap prend en charge de nombreuses options pour régler le comportement de swapping de htmx. Par exemple, par défaut htmx remplacera le titre d’une balise title trouvée n’importe où dans le nouveau contenu. Vous pouvez désactiver ce comportement en définissant le modificateur ignoreTitle
à true :
Les modificateurs disponibles sur hx-swap
sont :
Option | Description |
---|---|
transition | true ou false , indique si l’API de transition de vue doit être utilisée pour ce swap |
swap | Le délai de swap à utiliser (par exemple, 100ms ) entre le moment où l’ancien contenu est supprimé et le nouveau contenu est inséré |
settle | Le délai de stabilisation à utiliser (par exemple, 100ms ) entre le moment où le nouveau contenu est inséré et le moment où il est stabilisé |
ignoreTitle | Si défini sur true , tout titre trouvé dans le nouveau contenu sera ignoré et ne mettra pas à jour le titre du document |
scroll | top ou bottom , fait défiler l’élément cible vers son haut ou bas |
show | top ou bottom , fait défiler le haut ou le bas de l’élément cible dans la vue |
Tous les modificateurs de swap apparaissent après le style de swap spécifié et sont séparés par des deux-points.
Voir la documentation de l’attribut hx-swap pour plus de détails sur ces options.
Synchronisation
Souvent, vous souhaitez coordonner les requêtes entre deux éléments. Par exemple, vous pouvez vouloir qu’une requête d’un élément remplace la requête d’un autre élément ou attende que la requête de l’autre élément soit terminée.
htmx propose un attribut hx-sync pour vous aider à accomplir cela.
Considérez une condition de concurrence entre une soumission de formulaire et une requête de validation d’un input individuel dans ce HTML :
Sans utiliser hx-sync
, remplir l’input et soumettre immédiatement le formulaire déclenche deux requêtes parallèles vers /validate
et /store
.
Utiliser hx-sync="closest form:abort"
sur l’input surveillera les requêtes sur le formulaire et annulera la requête de l’input si une requête de formulaire est présente ou commence pendant que la requête de l’input est en cours :
Cela résout la synchronisation entre les deux éléments de manière déclarative.
htmx prend également en charge une méthode programmatique pour annuler les requêtes : vous pouvez envoyer l’événement htmx:abort
à un élément pour annuler toute requête en cours :
Plus d’exemples et de détails peuvent être trouvés sur la page de l’attribut hx-sync.
Transitions CSS
htmx facilite l’utilisation des Transitions CSS sans JavaScript. Considérez ce contenu HTML :
Imaginez que ce contenu soit remplacé par htmx via une requête AJAX avec ce nouveau contenu :
Notez deux choses :
- Le
div
a le mêmeid
dans le contenu original et dans le nouveau contenu. - La classe
red
a été ajoutée au nouveau contenu.
Dans cette situation, nous pouvons écrire une transition CSS de l’ancien état au nouvel état :
Lorsque htmx remplace ce nouveau contenu, il le fera de manière à ce que la transition CSS s’applique au nouveau contenu, vous offrant une transition fluide vers le nouvel état.
Donc, en résumé, tout ce que vous avez à faire pour utiliser les transitions CSS pour un élément est de garder son id
stable entre les requêtes !
Vous pouvez voir les Exemples d’Animations pour plus de détails et des démonstrations en direct.
Détails
Pour comprendre comment les transitions CSS fonctionnent réellement dans htmx, vous devez comprendre le modèle sous-jacent de remplacement et de stabilisation que htmx utilise.
Lorsque du nouveau contenu est reçu du serveur, avant que le contenu ne soit remplacé, le contenu existant de la page est examiné pour les éléments qui correspondent par l’attribut id
.
Si une correspondance est trouvée pour un élément dans le nouveau contenu, les attributs de l’ancien contenu sont copiés sur le nouvel élément avant que le remplacement n’ait lieu. Le nouveau contenu est ensuite remplacé, mais avec les anciennes valeurs d’attributs. Enfin, les nouvelles valeurs d’attributs sont remplacées, après un délai de stabilisation (20ms par défaut). Un peu fou, mais c’est ce qui permet aux transitions CSS de fonctionner sans JavaScript par le développeur.
Swaps Hors Bande
Si vous souhaitez échanger du contenu d’une réponse directement dans le DOM en utilisant l’attribut id
, vous pouvez utiliser l’attribut hx-swap-oob dans le HTML de la réponse :
Dans cette réponse, div#message
serait échangé directement dans l’élément DOM correspondant, tandis que le contenu supplémentaire serait échangé dans la cible de manière normale.
Vous pouvez utiliser cette technique pour « chevaucher » les mises à jour sur d’autres requêtes.
Tables Problématiques
Les éléments de table peuvent poser problème lorsqu’ils sont combinés avec des swaps hors bande, car, selon la spécification HTML, beaucoup ne peuvent pas exister seuls dans le DOM (par exemple, <tr>
ou <td>
).
Pour éviter ce problème, vous pouvez utiliser une balise template
pour encapsuler ces éléments :
Sélection du Contenu à Remplacer
Si vous souhaitez sélectionner un sous-ensemble du HTML de la réponse à échanger dans la cible, vous pouvez utiliser l’attribut hx-select, qui prend un sélecteur CSS et sélectionne les éléments correspondants dans la réponse.
Vous pouvez également choisir des morceaux de contenu pour un swap hors bande en utilisant l’attribut hx-select-oob, qui prend une liste d’identifiants d’éléments à choisir et à échanger.
Préservation du Contenu Pendant un Swap
Si vous souhaitez préserver un contenu à travers les swaps (par exemple, un lecteur vidéo que vous souhaitez laisser jouer même si un swap se produit), vous pouvez utiliser l’attribut hx-preserve sur les éléments que vous souhaitez préserver.
Paramètres
Par défaut, un élément qui provoque une requête inclura sa valeur s’il en a une. Si l’élément est un formulaire, il inclura les valeurs de tous les champs de saisie qu’il contient.
Comme pour les formulaires HTML, l’attribut name
du champ de saisie est utilisé comme nom de paramètre dans la requête envoyée par htmx.
De plus, si l’élément provoque une requête autre qu’un GET
, les valeurs de tous les champs de saisie du formulaire englobant le plus proche seront incluses.
Si vous souhaitez inclure les valeurs d’autres éléments, vous pouvez utiliser l’attribut hx-include avec un sélecteur CSS de tous les éléments dont vous souhaitez inclure les valeurs dans la requête.
Si vous souhaitez filtrer certains paramètres, vous pouvez utiliser l’attribut hx-params.
Enfin, si vous souhaitez modifier les paramètres de manière programmatique, vous pouvez utiliser l’événement htmx:configRequest .
Téléchargement de Fichiers
Si vous souhaitez télécharger des fichiers via une requête htmx, vous pouvez définir l’attribut hx-encoding sur multipart/form-data
. Cela utilisera un objet FormData
pour soumettre la requête, qui inclura correctement le fichier dans la requête.
Notez qu’en fonction de votre technologie côté serveur, vous devrez peut-être traiter les requêtes avec ce type de contenu de manière très différente.
Notez que htmx déclenche un événement htmx:xhr:progress
périodiquement basé sur l’événement progress
standard pendant le téléchargement, auquel vous pouvez vous connecter pour montrer la progression du téléchargement.
Consultez la section des exemples pour des modèles de formulaires plus avancés, y compris les barres de progression et la gestion des erreurs.
Valeurs Supplémentaires
Vous pouvez inclure des valeurs supplémentaires dans une requête en utilisant les attributs hx-vals (paires nom-expression au format JSON) et hx-vars (paires nom-expression séparées par des virgules et calculées dynamiquement).
Confirmation des Requêtes
Souvent, vous voudrez confirmer une action avant d’émettre une requête. htmx prend en charge l’attribut hx-confirm, qui vous permet de confirmer une action à l’aide d’une simple boîte de dialogue JavaScript :
En utilisant des événements, vous pouvez implémenter des boîtes de dialogue de confirmation plus sophistiquées. L’exemple de confirmation montre comment utiliser la bibliothèque sweetalert2 pour confirmer les actions htmx.
Confirmation des Requêtes avec des Événements
Une autre option pour faire une confirmation est via l’événement htmx:confirm
. Cet événement est déclenché sur chaque déclencheur de requête (pas seulement sur les éléments qui ont un attribut hx-confirm
) et peut être utilisé pour implémenter une confirmation asynchrone de la requête.
Voici un exemple utilisant sweetalert sur n’importe quel élément avec un attribut confirm-with-sweet-alert='true'
: