Un champ comme un autre

#Lien direct vers cette section

Un champ Ariane est un élément associé au formulaire qui le contient. Sa valeur entre dans FormData sous l'attribut name, comme celle d'un <input> :

<form id="inscription">
  <ar-datepicker name="naissance" label="Date de naissance" required></ar-datepicker>
  <button type="submit">Envoyer</button>
</form>

<script>
  document.getElementById('inscription').addEventListener('submit', (e) => {
    e.preventDefault();
    const data = new FormData(e.target);
    console.log(data.get('naissance')); // "2026-06-12"
  });
</script>

Sans attribut name, la valeur n'est pas soumise. Un champ disabled n'est ni soumis ni validé, y compris lorsqu'il est désactivé par un <fieldset disabled> parent :

<fieldset disabled>
  <!-- Désactivé par le fieldset, exclu de FormData -->
  <ar-datepicker name="naissance" label="Date de naissance"></ar-datepicker>
</fieldset>

Validation

#Lien direct vers cette section

Un formulaire contenant un champ invalide n'est pas soumis : le navigateur place le focus sur le premier champ en erreur et affiche son message. Ce texte vient des traductions du composant et suit son attribut lang : le navigateur ne localise pas le message d'un champ personnalisé, contrairement à un champ natif. Pour une langue non fournie, ou pour reformuler un message, voir Créer votre propre traduction (les termes validation…). Les contraintes viennent des attributs du champ (required, min et max pour une date…), documentés dans la page de chaque composant.

Pour plus d'information sur ce sujet, voir la documentation de la validation des contraintes sur MDN et la spécification HTML.

À savoir

Cette validation s'exécute dans le navigateur et ne remplace pas la validation côté serveur. novalidate sur le formulaire l'empêche de bloquer la soumission, mais la validité reste évaluée : :invalid, checkValidity() et :state(user-invalid) après une interaction restent disponibles. Seule la tentative de soumission ne marque plus les champs.

Champs obligatoires

#Lien direct vers cette section

L'attribut required bloque la soumission tant que le champ est vide, et l'annonce aux technologies d'assistance. Ariane n'affiche aucun indicateur : voir Styler les états pour ajouter un astérisque ou un texte.

Bien qu'afficher un indicateur du caractère obligatoire ne soit pas exigé par les critères d'accessibilité, il est utile à l'utilisateur. Si vous en ajoutez un, expliquez-le en haut du formulaire, par exemple « * champs obligatoires ».

Interroger la validité

#Lien direct vers cette section

L'API de validation standard est disponible sur l'élément :

const champ = document.querySelector('ar-datepicker');

champ.checkValidity();    // true ou false, sans rien afficher
champ.reportValidity();   // idem, et affiche le message du navigateur
champ.validity.valueMissing; // true si le champ est obligatoire et vide
champ.validationMessage;  // "Veuillez renseigner ce champ."

validity indique la contrainte en cause (valueMissing, rangeUnderflow, rangeOverflow, customError…). form, labels et willValidate sont aussi disponibles, comme sur un champ natif.

Messages d'erreur personnalisés

#Lien direct vers cette section

setCustomValidity() signale une erreur que le navigateur ne peut pas connaître, par exemple un refus du serveur. Le formulaire n'est plus soumis tant que l'erreur est là :

const champ = document.querySelector('ar-datepicker');

// Après un refus du serveur, par exemple
champ.setCustomValidity('Cette date est déjà réservée.');

// À l'application d'effacer l'erreur, par exemple à la prochaine saisie
champ.addEventListener('ar-datepicker-input-change', () => champ.setCustomValidity(''));

Comme sur un <input>, l'erreur persiste jusqu'à setCustomValidity(''), même après une nouvelle saisie ou une réinitialisation du formulaire : c'est à l'application de l'effacer.

Le composant n'affiche pas de message : pour en afficher un dans la page, utilisez le slot error. Un élément extérieur au composant ne peut pas être référencé par aria-describedby depuis l'intérieur de son shadow DOM : le slot le relie au champ, et il est annoncé aux lecteurs d'écran. Il n'a aucun effet sur la validité du formulaire :

<ar-datepicker label="Date de naissance">
  <span slot="error">Cette date est déjà réservée.</span>
</ar-datepicker>

Annoncer les erreurs

#Lien direct vers cette section

Le composant ne pose aucun rôle live sur le slot error : le message est relié au champ par aria-describedby et lu quand le champ reçoit le focus. À la soumission d'un formulaire, un role="alert" par champ déclencherait autant d'annonces qui s'interrompent. Affichez plutôt un récapitulatif des erreurs en tête du formulaire, annoncé une seule fois et avec un lien vers chaque champ, puis placez le focus sur ce récapitulatif ou sur le premier champ en erreur.

Pour annoncer un message dès son apparition, par exemple pour une validation en direct, posez le rôle sur votre propre élément :

<ar-datepicker label="Date de naissance">
  <span slot="error" role="alert">Cette date est déjà réservée.</span>
</ar-datepicker>

Pour plus d'information sur ce sujet, voir le tutoriel sur les notifications de formulaire du W3C.

Styler les états

#Lien direct vers cette section

:invalid et :valid s'appliquent nativement. La plateforme réserve les autres pseudo-classes de formulaire aux champs natifs : Ariane expose à leur place des états personnalisés, ciblés avec :state().

  • :state(required) et :state(optional) : selon l'attribut required.
  • :state(user-invalid) et :state(user-valid) : comme :user-invalid et :user-valid, ils n'apparaissent qu'après une interaction de l'utilisateur, une tentative de soumission ou reportValidity(). Une valeur posée par l'application ne les déclenche pas.
  • :state(has-error) : le slot error est rempli, l'application affiche une erreur. Il ne dépend pas de la validité du champ.
/* Indicateur de champ obligatoire */
ar-datepicker:state(required)::part(label)::after {
  content: ' *';
}

/* Validation du navigateur : champ invalide après une interaction */
ar-datepicker:state(user-invalid)::part(input) {
  border-color: var(--couleur-erreur);
}

/* Messages de l'application dans le slot error */
ar-datepicker:state(has-error)::part(input) {
  border-color: var(--couleur-erreur);
}

Le choix dépend de la manière de valider. Avec la validation du navigateur, ciblez :state(user-invalid). Si vous désactivez cette validation (novalidate) pour afficher vos propres messages dans le slot error, ciblez :state(has-error). Dans les deux cas, l'input porte aria-invalid, comme le fait un champ natif invalide après interaction.

Réinitialisation

#Lien direct vers cette section

form.reset() et un bouton type="reset" ramènent le champ à sa valeur initiale, celle du premier rendu. Aucun événement de valeur n'est émis, et les états user-invalid et user-valid sont retirés.

<form>
  <ar-datepicker name="naissance" value="2026-06-12" label="Date de naissance"></ar-datepicker>
  <button type="reset">Réinitialiser</button>
</form>