Formules
Vérifiez les réponses entre elles, à même le formulaire, en une seule ligne. end_date > start_date indique tout de suite
au visiteur que ses dates sont inversées, sans serveur à vous et sans code à héberger.
En écrire une
Ouvrez une question dans le générateur, puis Validations, et choisissez Formule. Écrivez ce qui doit être vrai, et le message à afficher quand ce ne l’est pas. Le générateur vous relit la formule en mots et vous indique quoi corriger pendant que vous tapez.
end_date > start_datePour afficher ou masquer une question, ouvrez Conditions et choisissez Avancé : écrire une formule. Une formule peut côtoyer vos autres règles dans un groupe.
quantity * unit_price >= 100Ajoutez quelques essais sous Essayer pour voir la réponse avant de publier. Ils restent pour la prochaine personne qui modifie le formulaire, et les visiteurs ne les voient jamais.
Ce que vous pouvez écrire
| Vous écrivez | Cela veut dire |
|---|---|
a + b, a - b, a * b, a / b, a % b | Arithmétique |
a == b, a != b, a < b, a <= b, a > b, a >= b | Comparer deux éléments |
country in ["CA", "US"] | L’une de ces valeurs |
a and b, a or b, not a | Combiner |
contact.phone | Une question dans un groupe |
items[].price, items[0].price | Une colonne d’un groupe répété, ou une rangée |
`first-name` | Une clé avec un trait d’union, un chiffre au début, ou le nom d’un mot ou d’une fonction |
Le texte s’écrit entre guillemets doubles ou simples, et les guillemets courbes d’un téléphone fonctionnent aussi. Il n’y a ni affectation, ni boucle, ni moyen d’atteindre quoi que ce soit hors des réponses de ce formulaire.
Fonctions
| Groupe | Fonctions |
|---|---|
| Vérifications | luhn(text), isEmpty(value), isEmail(text), isUrl(text), isPostalCode(text, "CA"), isPhone(text) |
| Texte | len, lower, upper, trim, contains, startsWith, endsWith, concat |
| Nombres | round(number, places), floor, ceil, abs, min, max |
| Listes | count, sum, contains, unique |
| Dates | date(text), today("America/Toronto"), daysBetween(from, to), dateOf(moment, "America/Toronto"), year, month, day |
| Logique | if(condition, a, b), coalesce(a, b, ...) |
luhn indique qu’un numéro est bien formé, rien de plus. Ne recueillez pas de numéros de carte dans un formulaire.
Quand une question n’a pas de réponse
Une question sans réponse est inconnue : une question facultative n’échoue donc jamais parce qu’elle est vide.
| Cas | Résultat |
|---|---|
| Arithmétique avec une question sans réponse | Inconnu |
<, <=, >, >= avec une question sans réponse | Inconnu |
==, !=, in | Donnent toujours une réponse. a == null est vrai quand a est sans réponse, et a != "CA" aussi |
| Une formule de validation qui finit inconnue | Passe. C’est Obligatoire qui exige une réponse |
| Une condition qui finit inconnue | Fausse. La règle ne s’applique pas encore |
| Une division par zéro | Inconnu |
Ainsi, country == "CA" comme validation échoue sur une réponse vide. Pour la permettre, écrivez isEmpty(country) or country == "CA".
Nombres et dates
Les nombres sont des décimales exactes : 0.1 + 0.2 == 0.3 est vrai partout, jusqu’à 30 chiffres significatifs et 12
décimales. Les dates sont des dates de calendrier, donc aucun fuseau horaire ne peut les déplacer. today exige un fuseau
horaire nommé, parce que l’aujourd’hui d’une entreprise et celui d’un visiteur ne sont pas toujours le même jour. On ne peut
pas comparer une date à un nombre, ni une date à du texte tant que date(field) n’a pas lu ce texte comme une date.
Qui peut lire une formule
Le navigateur des visiteurs exécute la formule pour répondre tout de suite, donc n’importe qui peut la lire. Le générateur vous avertit quand elle contient une valeur qui pourrait compter, comme un code. N’y mettez pas de secret.
Pour une vérification qui ne doit pas montrer sa logique, activez Vérifier seulement à l’envoi, et garder privé. Rien n’en arrive au navigateur, et l’erreur vient de notre serveur à l’envoi du formulaire. Même là, quelqu’un peut essayer des valeurs et lire les réponses : pour une vraie liste de secrets, faites la vérification sur votre propre serveur.
Afficher ou masquer une question doit fonctionner pendant la saisie, donc ces formules ne peuvent pas être privées. Une formule qui lit une liste est vérifiée seulement à l’envoi, et ne peut ni afficher ni masquer une question.
Nos serveurs refont chaque vérification, quoi qu’en dise le navigateur : sauter une formule dans le navigateur ne permet donc pas de la contourner. Une formule ne peut pas lire un champ de mot de passe, un destinataire, un expéditeur ni un identifiant d’accès.
Quand une question change
Si vous renommez une question ou la déplacez dans une section, le générateur met vos formules à jour à l’enregistrement. Si vous supprimez une question qu’une formule lit, le générateur nomme ce qui en dépend, et la formule s’affiche À corriger jusqu’à ce que vous la répariez. On ne peut pas publier un formulaire avec une formule à corriger, et les personnes sur une version précédente gardent cette version.
La condition d’un destinataire ne fait pas partie de la version publiée. Une formule à cet endroit lit chaque réponse telle qu’elle est arrivée : si elle nomme une question renommée, elle la lit comme sans réponse pour les envois faits avant le changement.
Limites
Une formule peut compter 1 000 caractères, 500 parties et 32 niveaux, et un formulaire peut en contenir jusqu’à 64 Ko. Une liste compte ses 1 000 premiers éléments, et au-delà, la formule est inconnue. Pour aller plus loin, séparez-la en deux règles.
Pour aller plus loin
Les formules en JSON
Une formule va partout où va une condition, et comme validateur d’une règle. Envoyez seulement text : le serveur écrit le
reste. Une règle faite uniquement de formules n’a pas besoin de when.
{
"validationRules": [
{
"id": "dates",
"then": [
{
"path": "end_date",
"validator": {
"type": "formula",
"formula": { "text": "end_date > start_date" },
"code": "END_BEFORE_START",
"message": "The end date has to be after the start date."
}
}
]
}
],
"visibilityRules": [
{
"id": "budget",
"path": "budget",
"default": "hidden",
"state": "visible",
"when": { "formula": { "text": "quantity * unit_price >= 100" } }
}
]
}Un schéma public envoie une formule sous la forme { "v": 1, "tree": { ... } }, sans texte. v est la version du langage
dans laquelle la formule a été enregistrée, et elle garde son sens pour de bon. Les fonctions et les résultats d’une version
ne changent pas.
Dans votre code
validateFormeriePublicFields exécute les formules d’un schéma une fois l’évaluateur chargé, et les formulaires dessinés par
la trousse le chargent d’eux-mêmes.
import { loadFormerieFormulas, validateFormeriePublicFields } from "@formerie/client";
await loadFormerieFormulas();
const result = validateFormeriePublicFields(schema, answers);Le paquet livre la spécification du langage dans @formerie/client/conformance/formula-v1.json. Chaque entrée s’exécute dans
le navigateur et sur nos serveurs.
Avec MCP
get_form_schema donne la grammaire et les fonctions. validate_form_definition vérifie une formule sans enregistrer, et formulaSamples l’essaie avec des réponses, sans rien conserver. update_form en enregistre une dans definitionPatch. Avec
MCP ou l’API, une formule qui ne passe pas est refusée avec son code FORMULA_, au lieu d’être gardée en brouillon à corriger
plus tard. Consultez Codes d’erreur.