Skip to main content
Voir en Markdown

Le composant formulaire

C'est dataSource qui décide du mode. Déclarez-en une et le formulaire est lié à une table : ses champs se résolvent contre les colonnes de cette table, et soumettre écrit un enregistrement via l'API des enregistrements. Omettez-la et le formulaire est statique : il collecte les champs déclarés sur lui et les soumet à un formulaire que vous avez déclaré dans forms[] (formRef) ou à une URL que vous nommez (endpoint). Rien d'autre ne change dans le composant.

Propriété Description
dataSource Liaison à une table uniquement, par conception : les écritures vont vers une table et jamais vers un point de lecture. mode: single fournit les valeurs courantes d'un formulaire d'édition.
formRef Nom d'une entrée de forms[] à laquelle soumettre.
endpoint L'URL de votre choix à laquelle soumettre : url, method, responseEnvelope, submitLabel, submitVariant, onSuccess, onError.
fields Les champs du formulaire, chacun avec field, un label, un control et un defaultValue optionnels.
fieldGroups Divise le formulaire en sections { label, fields }.
layout single-column par défaut, ou two-column, ou custom.
wizard Découpe le formulaire en étapes successives.
inlinePrefill Préremplit depuis un enregistrement existant sans quitter la page.
app.yaml
tables:
  - name: contacts
    fields:
      - { name: email, type: email }
      - { name: notes, type: long-text }
pages:
  - name: Contact
    path: /contacts/:id
    components:
      - type: form
        dataSource: { table: contacts, mode: single, param: id }
        layout: two-column
        action: { type: crud, operation: update, table: contacts }
        fields:
          - { field: email, label: 'Email address' }
          - { field: notes, control: textarea }

Soumettre à votre propre point d'entrée

endpoint est la troisième cible de soumission, à côté d'une table et d'une entrée de forms[] : le formulaire collecte ses champs déclarés et les envoie en POST sous forme de corps JSON — { [champ]: valeur } — à l'URL que vous nommez. Rien ne passe par l'API des enregistrements : la destination peut donc être une route de la plateforme, un point d'entrée d'administration, ou quelque chose qui vous appartient. Chaque champ doit alors nommer son propre control.

url est requise et accepte tout chemin ou toute URL complète. method vaut POST par défaut, ou PUT, ou PATCH. responseEnvelope décide de la façon dont le corps de la réponse est lu pour juger du succès ou de l'échec, et vaut sovrium par défaut. submitLabel surcharge le texte du bouton, onSuccess s'exécute sur un 2xx — une notification, plus les effets d'état client status, refetch et reload — et onError affiche une notification quand la soumission échoue.

submitVariant est fait pour une page qui empile plusieurs formulaires. Un formulaire dont la soumission est l'action principale de la page veut le remplissage primaire, et l'obtient en ne déclarant rien. Une page de réglages qui dessine six formulaires d'une ligne en colonne obtiendrait six boutons primaires, dont aucun n'est l'action principale — chacun déclare donc un poids plus discret et la page retrouve un point focal unique. Le vocabulaire est celui du composant button : default, destructive, outline, secondary, ghost, link, fab.

app.yaml
- type: form
  endpoint:
    url: /api/account/display-name
    method: POST
    submitLabel: Save
    submitVariant: secondary
    onSuccess: { type: toast, variant: success, message: Name saved }
    onError: { type: toast, variant: destructive, message: Could not save the name }
  fields:
    - { field: name, control: text, label: Display name }

La liste des membres est résolue par la même recette qu'emploie le composant bouton : une soumission et un bouton isolé qui demandent secondary ne peuvent donc pas diverger.

Préremplir un formulaire lié à un point d'entrée

Un champ lié à un point d'entrée porte son propre defaultValue. Rien ne le déduit d'une colonne — il n'y a pas de liaison à une table —, c'est donc le seul moyen pour un tel formulaire de s'ouvrir sur autre chose que des contrôles vides. Une valeur statique remplit un contrôle texte, et sur un select c'est l'option qui arrive déjà choisie.

Un defaultValue nommant $session.<champ> est la valeur propre à l'appelant, et il est rempli dans le navigateur plutôt qu'au rendu :

app.yaml
- type: form
  endpoint: { url: /api/invitations, method: POST, submitLabel: Send the invitation }
  fields:
    - { field: role, control: text, label: Role, defaultValue: member }
    - { field: invitedBy, control: text, label: Invited by, defaultValue: $session.name }
    - field: locale
      control: select
      label: Language
      defaultValue: fr
      options:
        - { value: en, label: English }
        - { value: fr, label: 'Français' }

Pourquoi l'identité n'est pas résolue sur le serveur. Une page est composée une fois et peut être mise en cache : résoudre $session.name au rendu inscrirait donc la première personne qui l'a demandée dans toutes les copies distribuées ensuite — le nom d'un lecteur arrivant dans le formulaire du suivant. Les octets servis ne nomment par conséquent personne : le serveur émet le gabarit et le navigateur le remplit contre la session de l'appelant. Un visiteur anonyme obtient un contrôle vide, jamais le littéral $session.name, et les valeurs par défaut statiques à côté ne sont pas affectées, puisqu'elles sont les mêmes pour tout le monde.

Les champs résolubles sont email, name, role et id — le même ensemble que résout le texte lié à la session, par le même mécanisme.

C'est le seul type qu'un specimen ne peut pas dessiner

form est exclu du catalogue du système de design. Il émet un contrôle de soumission sans condition, dans sa branche de création comme dans sa branche de mise à jour, et un cadre d'aperçu ne peut porter aucun chemin d'écriture — le catalogue rapporte donc le type et sa raison au lieu de le dessiner. C'est une règle de sûreté, pas un manque dans le kit.

Pages connexes

Dernière mise à jour 23 septembre 2026

Cette documentation a été rédigée avec de l'IA : des erreurs ou du contenu obsolète sont donc possibles. Sovrium est en bêta. Les contributions et corrections sont les bienvenues.

Construit avec Sovrium