Aller au contenu principal

Conditions de formulaire

La boîte de dialogue d'édition d'un écran est une liste à plat de champs. Certains champs n'ont de sens que quand d'autres ont une valeur spécifique — un SLA personnalisé qui n'apparaît que sur le plan Enterprise, un Email du responsable qui n'est obligatoire qu'au-delà de 20 % de remise. Le framework permet d'exprimer cela directement dans l'éditeur d'écrans, sur chaque champ, via trois emplacements :

EmplacementEffet
Visible quandLe champ n'est rendu que quand l'expression est vraie. Quand elle est fausse, le champ est retiré du dialogue et écarté du payload d'enregistrement.
Obligatoire quandLe champ obtient l'astérisque obligatoire et l'enregistrement est bloqué tant que la valeur n'est pas fournie.
Désactivé quandLe champ est rendu mais grisé et en lecture seule. Sa valeur courante part quand même dans le payload d'enregistrement.

Les trois emplacements sont indépendants — un champ peut être visible-et-obligatoire, visible-et-désactivé, ou les trois.


Vue d'ensemble

Abonnement — dialogue d'édition
Plan
Enterprise ▾
Sièges *
250
SLA personnalisé (visible : plan = enterprise)
Gold — 99,95 %
Remise % (désactivé : sièges < 100)
15
AnnulerEnregistrer

SLA personnalisé n'apparaît que sur le plan Enterprise ; Remise % est visible sur chaque plan mais verrouillé quand Sièges descend sous 100.


Modifier une condition

Dans Paramètres → Écrans, ouvrir l'écran et cliquer sur le champ dans l'onglet Champs. L'éditeur de champ à droite expose les trois emplacements de condition, chacun avec un éditeur d'expression :

Éditeur de champ — SLA personnalisé
Nom
custom_sla
Libellé
SLA personnalisé
Type
string ▾
Visible quand
plan == 'enterprise'
Obligatoire quand
— toujours obligatoire quand visible —
Désactivé quand

Chaque emplacement d'expression :

  • Suggère les noms de champs du même écran par auto-complétion.
  • Valide la syntaxe en direct — une faute de frappe (plan = 'enterprise' au lieu de ==) affiche un soulignement rouge avant l'enregistrement.
  • Refuse les cycles à l'enregistrement (champ A visible-quand dépend de B, B dépend de A).

Le bouton Tester en haut de l'éditeur de champ ouvre un petit volet d'aperçu (voir Tester les conditions plus bas).


Syntaxe des expressions

Le langage d'expression est petit et sûr — comparable à une clause SQL WHERE mais évalué côté client.

ConstructionExemple
Référence de champplan, seats, discount_pct. Référence à la valeur courante du champ portant ce Nom dans le même dialogue.
Littéraux'enterprise', 5, true, false, null.
Comparaisons==, !=, <, <=, >, >=.
Logique&&, ||, !. Parenthèses pour le groupement.
Appartenanceplan in ['team', 'enterprise'].
Test de nulldiscount_pct == null / discount_pct != null.
Prédicats de chaînename.startsWith('FR-'), name.endsWith('.pdf'), name.includes('test').
Longueurtags.length > 0 (pour les champs Multiple).
Contexte de sessionsession.user, session.lang, session.roles — le même triplet disponible aux requêtes (voir Liaison des paramètres → Contexte de session). session.roles est un tableau — 'admin' in session.roles.

Le langage n'a pas d'appels de fonction au-delà des prédicats listés ni d'opérateurs arithmétiques autres que la comparaison. L'intention est « expression booléenne sur l'état du formulaire », pas un langage de script.


Ordre d'évaluation

Les conditions sont ré-évaluées à chaque changement de champ dans le dialogue. Le framework exécute les trois emplacements pour chaque champ en parallèle ; le résultat est lu une fois chaque référence résolue. Ce que cela veut dire :

  • L'ordre dans lequel les champs sont listés n'a pas d'importance. Un Visible quand sur le champ A peut référencer le champ B qui lui-même dépend du champ C — le résolveur exécute la passe complète une fois par changement.
  • Les cycles sont refusés à l'enregistrement — l'éditeur nomme le cycle et pointe les champs en cause.
  • Les champs désactivés gardent leur valeur, même si un Visible quand les masque ensuite. Basculer la visibilité off puis on ne remet pas la valeur à zéro.
  • Les champs masqués perdent leur valeur à l'enregistrement. Le payload envoyé au connecteur ne contient que les champs visibles. Cela compte quand l'INSERT/UPDATE d'un connecteur attend NULL pour un champ absent plutôt que la valeur tapée précédemment.

Interaction avec Défaut

ScénarioComportement
Champ avec Défaut, devient visibleLa valeur par défaut est appliquée la première fois que le champ devient visible si il n'a pas encore de valeur. Le masquer puis le ré-afficher garde ce que l'utilisateur a tapé entre-temps.
Champ avec Défaut, devient masquéLa valeur n'est pas effacée en mémoire ; elle est écartée du payload d'enregistrement car le champ n'est plus rendu.
Champ sans Défaut, devient visibleLe champ se rend vide.
Champ avec Défaut ${session.user}, devient visibleLa valeur de session est substituée au moment de l'évaluation (même syntaxe que les valeurs par défaut de requête).

Les valeurs par défaut côté serveur (SEQUENCE, SYSDATE, LOGIN, PASSWORD — voir Dictionnaire) sont appliquées à l'enregistrement et n'interagissent pas avec les conditions.


Application côté serveur

Les conditions sont évaluées côté client pour l'UX en direct et ré-évaluées côté serveur à l'enregistrement pour se prémunir contre la manipulation. L'endpoint d'enregistrement :

  1. Reçoit le payload de champ.
  2. Réexécute chaque condition avec les valeurs du payload.
  3. Refuse l'enregistrement quand un champ obligatoire-et-visible manque ou quand un champ désactivé est modifié (sa valeur dans le payload diffère de la valeur dernièrement envoyée au client).

Les conditions sont donc des règles métier, pas seulement des indices UX. Un utilisateur qui ouvre l'onglet réseau et modifie le payload directement bute sur la même validation que le formulaire.


Tester les conditions

Le bouton Tester de l'éditeur de champ ouvre un petit volet d'aperçu : le dialogue rempli avec les valeurs de fixture issues du _test_row du connecteur (ou vide quand aucun n'est configuré) ; modifier les champs dont dépendent les conditions montre le comportement en direct.

Pour la logique non triviale, l'éditeur d'écran expose aussi un onglet Cas de test. Chaque cas de test est une paire { inputs, expected } que le bouton Exécuter les tests rejoue :

Cas de testEntréesAttendu
starter-planplan = starter, seats = 5custom_sla = hidden, discount_pct = disabled, manager_email = hidden
enterprise-with-discountplan = enterprise, seats = 250, discount_pct = 25custom_sla = visible, discount_pct = enabled, manager_email = visible+required

Le lanceur de tests affiche une coche verte par réussite, un diff rouge par échec. Les cas de test ne sont pas utilisés à l'exécution — ils documentent la logique du formulaire et survivent mieux aux refactorings que les vérifications visuelles.


Permissions

session.roles est l'interrupteur au niveau ligne. Un champ que seuls les superutilisateurs doivent modifier devient :

Désactivé quand : 'admin' not in session.roles

L'application côté serveur rend cela sûr — un utilisateur régulier qui modifie le payload réseau bute sur la même condition.


Sous le capot

Les conditions sont enregistrées comme chaînes d'expression sur chaque champ de l'entrée d'écran. Les opérateurs n'éditent pas le TOML sous-jacent à la main ; l'éditeur de champ est l'interface canonique et valide chaque expression avant l'enregistrement.


Pour aller plus loin