Validation
Vue d'ensemble
rs-grid valide une édition de cellule avant qu'elle soit validée. La validation s'exécute en deux couches, vérifiées dans l'ordre :
- Règles déclaratives (
ColumnDef::rules: Vec<ValidationRule>) — la façon recommandée de valider. Les règles intégrées couvrent les cas courants (Required,MinLength,MaxLength,Range,OneOf), plus une échappatoireCustom. - Validateur historique (
ColumnDef::validator: Option<CellValidator>) — une closure libre, toujours prise en charge pour compatibilité ascendante. Il ne s'exécute qu'une fois toutes les règles passées.
La validation est appliquée à l'intérieur de GridState::apply, pas
seulement au niveau de l'interface — elle s'applique donc à tout
consommateur (tests natifs, rendu canvas, tout futur renderer personnalisé).
Elle est aussi vérifiée en dehors d'une session d'édition : coller ignore
les cellules cibles invalides (voir Validation au collage ci-dessous), et
le rendu canvas signale toute cellule dont la valeur actuelle échoue la
validation même si elle n'a jamais été éditée (voir Indicateur au repos
ci-dessous).
Ajouter des règles
Le sucre syntaxique sur ColumnDef couvre les cas courants :
Ou définissez la liste complète directement avec ValidationRule, par
exemple pour une règle Custom :
Variantes de ValidationRule :
Les règles s'exécutent dans l'ordre, la première échec l'emporte. Une fois toutes les règles passées, le validateur historique (s'il est défini) s'exécute toujours :
Annuler ou bloquer : InvalidEditMode
GridModel::invalid_edit_mode (par défaut Revert) contrôle ce qui se
passe quand un CommitEdit échoue à la validation :
Le définir à la construction :
ou le basculer à l'exécution avec GridCommand::SetInvalidEditMode(mode).
Les deux modes émettent CommandOutput::ValidationError { row, col_key, message }.
Retour live pendant la saisie
GridCommand::ValidateEdit { value } revérifie la valeur en cours d'édition
sans valider — c'est un no-op sans édition active et ça ne crée aucune
entrée d'annulation. rs-grid-web le déclenche automatiquement à chaque
frappe, si bien que l'édition en cours reflète toujours l'état de
validation courant, pas seulement la dernière tentative de validation.
Lire l'état live à la demande :
Some((row, col_key, message)) tant que l'édition en cours est invalide,
None sinon.
Écouter la validation
Il existe deux callbacks — choisissez selon le moment où vous devez réagir :
rs-grid n'impose pas de widget d'erreur de validation (pas de composant tooltip intégré) — il expose l'état brut pour que vous puissiez en construire un avec votre propre framework/CSS.
Positionner une interface de validation personnalisée
GridCanvas::cell_client_rect(row, col_key) retourne le rectangle en
espace client de la cellule (left, top, width, height) en pixels CSS
relatifs à la page — prêt à positionner un tooltip ou une bannière en
position: fixed à côté de la cellule en erreur :
Retourne None si col_key n'existe pas. C'est de la géométrie pure — ça
ne vérifie pas si la cellule est actuellement visible dans le viewport.
Indicateur au repos
Une cellule peut être invalide sans jamais avoir été éditée — par exemple
chargée ainsi depuis la source de données. Le rendu canvas vérifie la
valeur actuelle de chaque cellule visible via ColumnDef::validate_value
et, en cas d'échec, dessine une bordure thémée (Theme::invalid_cell_border
/ --rs-grid-invalid-cell-border) autour d'elle — aucun clic ni session
d'édition requis. C'est indépendant du style invalide de l'éditeur en ligne
décrit plus haut (et ça ne l'attend pas) ; ça se déclenche uniquement à
partir de la valeur actuelle de la cellule.
Un invalid_cell_border transparent (alpha 0) désactive entièrement
l'indicateur, même convention que locked_cell_bg.
Info-bulle au survol des cellules invalides
Survoler une cellule invalide au repos affiche une info-bulle — un seul élément DOM réutilisé pour toutes les cellules (pas un par cellule invalide, donc le coût est identique qu'il y ait une seule cellule invalide ou des milliers), positionné automatiquement sur la cellule survolée. rs-grid ne dessine aucun visuel par défaut : la classe est entièrement à vous, ce qui permet de reproduire directement l'info-bulle de daisyUI :
tooltip-open (ou un modificateur équivalent toujours ouvert) est
indispensable — cet élément ne reçoit jamais de vrai :hover de la souris
(il est posé au-dessus du canvas avec pointer-events: none), donc rs-grid
gère lui-même l'ouverture/fermeture via son propre attribut display
plutôt que de compter sur :hover en CSS. Sans classe configurée,
l'élément existe mais reste invisible.
Le message de validation est exposé via l'attribut standard data-tip,
que daisyUI (et tout CSS utilisant content: attr(data-tip)) lit
directement — inutile de dupliquer le texte du message soi-même.
Pour vérifier la validité au repos d'une cellule en dehors du survol (par
exemple pour un indicateur personnalisé), utilisez
canvas.cell_validation_error(row, col_key) -> Option<String> —
indépendant de toute session d'édition active, contrairement à
validation_error() plus haut.
Validation au collage
GridCommand::PasteAt valide chaque valeur entrante avant de l'écrire dans
la cellule cible — une cellule dont la valeur collée échoue la validation
est silencieusement ignorée (l'écriture n'a pas lieu), tandis que le reste
du bloc collé s'applique normalement. Ça reflète le comportement d'Excel et
AG Grid sur le même cas : aucun des deux ne bloque un collage entièrement,
et quand un rejet existe il est toujours par cellule, jamais tout-ou-rien.
GridCommand::CutSelection vide les cellules en y écrivant une chaîne
vide — ça reste une écriture, donc c'est validé de la même façon : une
cellule dont les règles rejettent une valeur vide (ex. .required())
garde sa valeur d'origine plutôt que d'être vidée. Le texte copié dans le
presse-papiers n'est pas affecté dans un cas comme dans l'autre — le
couper copie toujours les valeurs d'origine en premier.
Repli tooltip natif title
Par défaut, l'<input> d'édition en ligne reçoit un attribut title natif
reflétant le message de validation courant — un tooltip navigateur
zero-config qui ne nécessite aucune intégration. Désactivez-le une fois
votre propre interface branchée, pour que les deux ne se concurrencent pas :
Comportement
- La validation s'exécute sur les éditions utilisateur (
CommitEdit/ValidateEdit) et surPasteAt(voir Validation au collage ci-dessus). Les écritures programmatiques directes viaGridModel::set_cellla contournent toujours — c'est l'API de plus bas niveau et elle n'a volontairement aucune couche de validation propre. - Les éditeurs
Selectsont validés aussi — la valeur de l'option sélectionnée est vérifiée comme n'importe quelle autre. - Les règles et le validateur historique sont synchrones. Pour une
validation asynchrone (ex. vérification serveur), validez de façon
optimiste puis revenez en arrière avec
GridCommand::Undosi la vérification échoue côté serveur. - Le mode
Revertne crée aucune entrée d'annulation ; le modeBlocknon plus, puisque la session d'édition ne se ferme jamais en cas d'échec.
Voir aussi
- Édition — cycle de vie de l'édition et types d'éditeurs
- API ColumnDef — référence des types
ValidationRule/CellValidator - API GridCommand —
ValidateEdit,SetInvalidEditMode - Annuler / Rétablir — comportement de la pile d'annulation

