Aller au contenu principal

Onglets imbriqués

Un dialogue avec tous ses champs sur un seul formulaire couvre le cas mono-ligne. Quand une ligne a des données liées — un client avec plusieurs adresses, un utilisateur avec des paramètres par application, une commande avec des lignes de poste — on intègre ces données liées directement dans le dialogue comme un onglet imbriqué.

Deux variantes :

Type d'ongletCe qu'il afficheQuand
nested_formUn formulaire d'enregistrement enfant : zéro ou une ligne liée, avec ses propres requêtes SELECT / INSERT / UPDATE.Quand la table liée a au plus une ligne par parent (un-vers-un ou zéro-vers-un).
nested_tableUne TableView complète des lignes liées, intégrée en ligne — affiche la grille d'un autre écran restreinte à la clé du parent.Quand la table liée a plusieurs lignes par parent (un-vers-plusieurs).

Les deux s'attachent au dialogue comme n'importe quel autre onglet ; l'utilisateur clique entre eux sans quitter le formulaire.


Quand choisir lequel

PatronChoisir
Un client → au plus une adresse de facturation.nested_form.
Un client → plusieurs commandes.nested_table.
Une application → ses paramètres spécifiques JD Edwards (zéro ou une ligne).nested_form.
Un projet → ses lignes de poste.nested_table.
Un employé → son affectation actuelle (une ligne).nested_form.
Un employé → l'historique de ses affectations.nested_table.

Le validateur _check du schéma impose l'unicité des identifiants d'onglet ; sinon les deux types peuvent coexister dans le même dialogue — un dialogue Client avec un nested_form sur Facturation et un nested_table sur Commandes est une forme naturelle.


nested_form — un formulaire d'enregistrement enfant

Un onglet nested_form intègre un sous-dialogue qui lit / écrit une table liée. La clé primaire du parent se lie à la requête de lecture imbriquée ; si une ligne revient, le formulaire s'affiche en mode édition ; sinon, en mode ajout.

Inspecteur · Onglet "Facturation" · type=nested_formconnector(connecteur du parent — crm)read_query *billing_address_get ▾update_querybilling_address_put ▾insert_querybilling_address_post ▾LIAISONS DE PARAMÈTRES (parent → imbriqué):CUSTOMER_ID← colonne parentCUSTOMER_ID(la ligne courante du dialogue parent)+ Ajouter une liaisonCHAMPSGlisser des champs depuis la Palette comme sur un onglet de formulaire normal.

Champs

ChampNotes
connectorConnecteur qui héberge les requêtes imbriquées. Vide = connecteur du parent.
read_query (obligatoire)Lit la ligne liée. Doit retourner 0 ou 1 ligne après que la liaison la restreint.
update_queryÉcrit les modifications quand une ligne liée existe déjà.
insert_queryÉcrit une nouvelle ligne liée quand aucune n'existait (après que la liaison a retourné 0 ligne).
param_bindsLie les colonnes du parent aux paramètres :placeholder des requêtes imbriquées. Typiquement :CUSTOMER_ID ← CUSTOMER_ID.
fieldsLes champs du formulaire, comme sur un onglet form normal. Glisser depuis la Palette.
colsNombre de colonnes de la grille pour le formulaire imbriqué.

Comportement

Quand le dialogue parent s'ouvre :

  1. La read_query se déclenche avec les valeurs des colonnes du parent liées via param_binds.
  2. Si une ligne revient, le formulaire imbriqué s'affiche en mode édition — les champs sont renseignés, Enregistrer déclenche update_query.
  3. Si aucune ligne ne revient, le formulaire imbriqué s'affiche en mode ajout — les champs sont vides, Enregistrer déclenche insert_query.

L'Enregistrer du parent et l'Enregistrer de l'onglet imbriqué sont indépendants — enregistrer le parent ne touche pas aux données imbriquées ; enregistrer l'imbriqué ne déclenche pas la chaîne Enregistrer du parent. Chacun opère sur sa propre ligne.

Cas d'usage — paramètres spécifiques JD Edwards

Un dialogue Paramètres → Applications avec un onglet JD Edwards qui n'apparaît que quand l'application est une application JDE :

[[screens.nomasx1.settings_applications.dialog.tabs]]
id = "jde"
label = "JD Edwards"
type = "nested_form"
read_query = "settings_jde_get"
update_query = "settings_jde_put"
insert_query = "settings_jde_post"

[[screens.nomasx1.settings_applications.dialog.tabs.param_binds]]
param = "APPS_ID"
source = "APPS_ID"

[[screens.nomasx1.settings_applications.dialog.tabs.fields]]
name = "JDE_VERSION"

[[screens.nomasx1.settings_applications.dialog.tabs.fields]]
name = "JDE_ENVIRONMENT"

Quand l'utilisateur ouvre le dialogue Applications sur une application JDE (APPS_ID = une valeur), l'onglet JDE charge la ligne de paramètres correspondante et permet à l'utilisateur de la modifier. Pour les applications non-JDE où aucune ligne n'existe, le même onglet pré-remplit le formulaire pour que l'utilisateur puisse en ajouter une.


nested_table — une grille de lignes liées

Un onglet nested_table intègre la TableView d'un autre écran en ligne. Pas de nouveaux champs — la grille complète + le dialogue de l'écran cible s'affichent à l'intérieur de l'onglet, restreints à la clé du parent.

Inspecteur · Onglet "Affaires" · type=nested_tableconnector(connecteur du parent — crm)screen *deals ▾LIAISONS DE PARAMÈTRES (parent → read_query de l'écran imbriqué):CUSTOMER_ID← colonne parentCUSTOMER_ID+ Ajouter une liaisonUn onglet nested-table intègre la TableView d'un autre écran — ses lignes / colonnes proviennent de cet écran, pas de cet onglet. Aucun champ à configurer ici.

Champs

ChampNotes
connectorConnecteur qui héberge l'écran cible. Vide = connecteur du parent.
screen (obligatoire)L'identifiant de l'écran cible. Le sélecteur s'alimente depuis la liste d'écrans du même connecteur.
param_bindsLie les colonnes du parent aux paramètres :placeholder de la read_query de l'écran cible.

Comportement

L'onglet affiche l'écran cible — sa grille, ses filtres, son dialogue d'ajout / modification, son menu contextuel ligne — exactement comme il le ferait sur sa propre page, mais restreint par les paramètres liés. L'utilisateur peut :

  • Parcourir les lignes liées dans la grille intégrée.
  • Ouvrir le bouton + Ajouter pour créer une nouvelle ligne liée — les colonnes parent liées pré-remplissent les colonnes correspondantes du dialogue d'ajout.
  • Faire un clic droit pour le menu contextuel ligne de l'écran cible.
  • Cliquer sur le bouton d'édition en ligne pour ouvrir le dialogue de l'écran cible et modifier une ligne liée.

Cas d'usage — client + affaires

Un dialogue Client avec un onglet Affaires affichant chaque affaire pour ce client :

[[screens.crm.customers.dialog.tabs]]
id = "deals"
label = "Affaires"
type = "nested_table"
screen = "deals"

[[screens.crm.customers.dialog.tabs.param_binds]]
param = "CUSTOMER_ID"
source = "CUSTOMER_ID"

L'onglet Affaires intègre la TableView de l'écran deals, filtrée sur le client courant. Quand l'utilisateur clique sur + Ajouter une affaire dans la grille intégrée, le CUSTOMER_ID de la nouvelle affaire est pré-rempli avec la valeur du parent.

Ce qui s'affiche à l'intérieur

La TableView intégrée porte tout ce que l'écran cible possède :

ÉlémentHérité
Colonnes + leurs indications
Filtres✓ — l'utilisateur peut restreindre davantage dans la portée du parent.
Dialogue (ajout / modification)
Actions (barre d'outils / menu ligne / hooks)
Configuration d'export

L'écran cible existe indépendamment — on peut y naviguer comme page autonome ET l'intégrer comme onglet imbriqué. La même configuration pilote les deux surfaces.


Quand imbriquer vs. quand naviguer

Une décision courante : les données liées doivent-elles être intégrées dans le dialogue du parent, ou s'ouvrir comme un écran séparé au clic sur la ligne ?

Choisir l'intégrationChoisir la navigation au clic
L'utilisateur veut toujours voir les données liées aux côtés du parent (flux mono-écran).Les données liées ne sont qu'occasionnellement pertinentes ; les ouvrir à la demande maintient le dialogue parent focalisé.
La table liée est petite (quelques colonnes, peu de lignes).La table liée est grande ; l'intégration encombre le dialogue.
Les utilisateurs modifient les deux en même temps.Les utilisateurs modifient typiquement l'un puis l'autre en étapes séparées.
Plusieurs écrans voisins descendent vers la même cible — la définir une fois comme écran autonome est plus propre.

L'intégration est le choix à forte affinité pour les relations obligatoires (un client avec au moins une adresse) ; le clic est le bon choix pour les données larges (un client avec des centaines de commandes historiques).


Permissions sur les données imbriquées

Les onglets imbriqués honorent le même modèle de permissions que les écrans autonomes — la permission sql:<connector>:<query> de la requête sous-jacente est vérifiée. Un utilisateur qui peut voir le dialogue parent mais qui n'a pas la permission sur la requête de lecture imbriquée voit l'onglet imbriqué vide / en lecture seule / masqué selon la permission manquante :

Permission manquanteEffet sur l'onglet imbriqué
sql:<connector>:<nested_read>L'onglet est entièrement masqué.
sql:<connector>:<nested_update>Le formulaire est en lecture seule.
sql:<connector>:<nested_insert>Le bouton + Ajouter est masqué.
sql:<connector>:<nested_delete>La suppression de ligne est désactivée.

Cela permet de construire des dialogues qui révèlent progressivement les données selon le rôle de l'utilisateur — même définition d'écran, surfaces différentes par utilisateur.


Pièges courants

ErreurSymptômeCorrection
nested_form.read_query retourne plus d'une ligne.Le formulaire n'affiche que la première ligne et ignore silencieusement le reste.Resserrer la liaison pour que la lecture retourne 0 ou 1. Utiliser nested_table pour les véritables relations un-vers-plusieurs.
nested_table sans param_binds.La grille intégrée affiche toutes les lignes de la cible — y compris les lignes non liées.Toujours lier au moins les colonnes clé étrangère du parent.
nested_form avec insert_query vide, aucune ligne n'existe encore.L'utilisateur ne peut pas ajouter de nouvelle ligne — le formulaire n'a rien à déclencher.Câbler insert_query, ou pré-créer la ligne via un autre flux.
nested_table pointant sur un écran d'un autre connecteur + surcharge connector manquante.Le runtime tente de résoudre l'écran cible sur le connecteur du parent et échoue.Renseigner connector explicitement sur le connecteur de l'écran cible.
Deux onglets imbriqués avec le même id.La validation à l'enregistrement échoue (« identifiant d'onglet de dialogue en double »).Choisir des identifiants uniques par dialogue.

Étapes suivantes