Skip to Content
DocumentationFormulaires dans O3Utiliser les formulaires dans les applications

Utiliser les formulaires dans les applications

Une fois que vous avez créé un formulaire à l’aide du Form Builder ou converti un formulaire HTML Form Entry existant, vous devrez l’intégrer dans votre application. Le React Form Engine offre des moyens flexibles de rendre les formulaires dans différents contextes, des espaces de travail du dossier patient aux applications personnalisées.

Vue d’ensemble

Le React Form Engine peut être utilisé de deux manières principales :

  1. Extension Form Renderer - Un composant pré-construit qui gère le chargement des formulaires, le rendu et l’intégration dans les espaces de travail. C’est le moyen le plus simple de rendre les formulaires dans les espaces de travail.
  2. Composant FormEngine - Le composant principal qui offre un contrôle total sur le rendu des formulaires, la soumission et le comportement.

Rendre les formulaires dans les espaces de travail

Le dossier patient fournit déjà un espace de travail de saisie de formulaire via @openmrs/esm-patient-forms-app. Pour la plupart des flux du dossier patient, lancez patient-form-entry-workspace avec un objet formulaire et, si nécessaire, les détails de la rencontre au lieu d’enregistrer votre propre espace de travail :

import { launchWorkspace2 } from '@openmrs/esm-framework'; import { type Form } from '@openmrs/esm-patient-common-lib'; function launchMyForm(form: Form, encounterUuid?: string) { launchWorkspace2('patient-form-entry-workspace', { form, encounterUuid, additionalProps: { mode: encounterUuid ? 'edit' : 'enter', }, }); }
ℹ️

patient-form-entry-workspace lit patient, patientUuid, visitContext et mutateVisitContext depuis le groupe d’espace de travail du dossier patient. Lancez-le depuis le dossier patient, ou créez votre propre enveloppe d’espace de travail si le formulaire doit s’exécuter en dehors de ce contexte.

Cet espace de travail encapsule le formulaire dans Workspace2, rend le visit-context-header-slot, puis rend soit un iframe HTML Form Entry, soit le React Form Engine via le form-widget-slot.

Créer un espace de travail de formulaire personnalisé

ℹ️

L’extension react-form-engine-widget est enregistrée par @openmrs/esm-form-engine-app dans le slot form-widget-slot. Vous n’avez besoin d’un espace de travail personnalisé que si vous voulez une enveloppe d’espace de travail différente, un comportement d’actualisation personnalisé ou un contexte de rendu hors du dossier patient.

Si vous créez votre propre espace de travail pour le dossier patient, enregistrez-le avec les routes Workspace v2 et placez sa fenêtre dans le groupe patient-chart :

{ "workspaces2": [ { "name": "my-form-workspace", "component": "myFormWorkspace", "window": "my-form-window" } ], "workspaceWindows2": [ { "name": "my-form-window", "group": "patient-chart", "width": "extra-wide", "canMaximize": true } ] }

Rendez ensuite form-widget-slot depuis une enveloppe Workspace2 et transmettez l’état attendu par le renderer de formulaire :

import React, { useState } from 'react'; import { ExtensionSlot, Workspace2 } from '@openmrs/esm-framework'; import { useSWRConfig } from 'swr'; import { invalidateVisitAndEncounterData, type PatientWorkspace2DefinitionProps, type FormRendererProps, } from '@openmrs/esm-patient-common-lib'; interface MyFormWorkspaceProps { formUuid: string; encounterUuid?: string; } export function MyFormWorkspace({ closeWorkspace, workspaceProps: { formUuid, encounterUuid }, groupProps: { patient, patientUuid, visitContext, mutateVisitContext }, }: PatientWorkspace2DefinitionProps<MyFormWorkspaceProps, object>) { const { mutate: globalMutate } = useSWRConfig(); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); const state: FormRendererProps = { formUuid, patient, patientUuid, encounterUuid: encounterUuid ?? '', visit: visitContext, visitUuid: visitContext?.uuid, closeWorkspace, closeWorkspaceWithSavedChanges: () => { mutateVisitContext?.(); invalidateVisitAndEncounterData(globalMutate, patientUuid); return closeWorkspace({ discardUnsavedChanges: true }); }, setHasUnsavedChanges, additionalProps: { mode: encounterUuid ? 'edit' : 'enter', }, }; return ( <Workspace2 title="Mon formulaire" hasUnsavedChanges={hasUnsavedChanges}> <ExtensionSlot name="form-widget-slot" state={state} /> </Workspace2> ); }

closeWorkspaceWithSavedChanges fait partie de l’état FormRendererProps transmis à form-widget-slot. Utilisez-le pour actualiser les données après l’enregistrement avant de fermer l’espace de travail. Le closeWorkspace de Workspace v2 continue de gérer les annulations ou fermetures ordinaires.

Lancez l’espace de travail personnalisé avec Workspace v2 :

import { launchWorkspace2 } from '@openmrs/esm-framework'; function launchMyCustomWorkspace(formUuid: string) { launchWorkspace2('my-form-workspace', { formUuid, }); }

Cet exemple de lancement suppose qu’il s’exécute depuis une extension ou une page du dossier patient, afin que les props du groupe patient-chart soient disponibles pour l’espace de travail.

💡

L’extension form renderer gère automatiquement le chargement du schéma de formulaire, les états d’erreur et la gestion du cycle de vie de l’espace de travail. C’est l’approche recommandée pour la plupart des cas d’usage.

Utiliser FormEngine directement

Pour plus de contrôle sur le rendu et le comportement des formulaires, vous pouvez utiliser le composant FormEngine directement depuis @openmrs/esm-form-engine-lib. C’est utile lorsque vous avez besoin d’une gestion personnalisée de la soumission, souhaitez rendre les formulaires en dehors des espaces de travail, ou avez besoin d’un contrôle précis sur le comportement du formulaire.

Utilisation de base

import React from 'react'; import { type Encounter } from '@openmrs/esm-framework'; import { FormEngine, type FormSchema } from '@openmrs/esm-form-engine-lib'; interface MyFormComponentProps { patientUuid: string; formSchema: FormSchema; } export function MyFormComponent({ patientUuid, formSchema }: MyFormComponentProps) { const handleSubmit = (encounters: Array<Encounter>) => { console.log('Formulaire soumis :', encounters); // Gérer la soumission du formulaire }; return ( <FormEngine patientUUID={patientUuid} formJson={formSchema} onSubmit={handleSubmit} /> ); }

Charger le schéma de formulaire depuis l’UUID

Si vous avez un UUID de formulaire au lieu du schéma, transmettez-le à la prop formUUID. Le FormEngine chargera automatiquement le schéma :

import React from 'react'; import { FormEngine } from '@openmrs/esm-form-engine-lib'; interface MyFormComponentProps { patientUuid: string; formUuid: string; } export function MyFormComponent({ patientUuid, formUuid }: MyFormComponentProps) { return ( <FormEngine patientUUID={patientUuid} formUUID={formUuid} /> ); }
💡

Le FormEngine gère les états de chargement et les erreurs en interne. Vous n’avez pas besoin de récupérer manuellement le schéma du formulaire sauf si votre cas d’usage l’exige.

Props et configuration du formulaire

Le composant FormEngine accepte les props suivantes :

Props requises

  • patientUUID (string) - L’UUID du patient pour lequel le formulaire est rempli

Props optionnelles

  • formUUID (string) - L’UUID du formulaire à charger depuis le serveur. Si fourni, le schéma du formulaire sera chargé automatiquement. Ne peut pas être fourni avec formJson : vous devez utiliser soit formUUID, soit formJson, mais pas les deux.
  • formJson (FormSchema) - L’objet schéma de formulaire. Utilisez-le lorsque vous avez déjà le schéma chargé ou souhaitez utiliser un schéma personnalisé.
  • encounterUUID (string) - L’UUID d’une rencontre existante à modifier. Lorsqu’il est fourni, le formulaire sera pré-rempli avec les données de la rencontre et rendu en mode édition.
  • visit (Visit) - L’objet visite à associer à la rencontre soumise. L’espace de travail de formulaire du dossier patient fournit la visite active pour les nouveaux formulaires, ou la visite de la rencontre lorsque vous modifiez une rencontre existante.
  • mode ('enter' | 'edit' | 'view' | 'embedded-view') - Le mode de rendu du formulaire. Voir Modes de rendu des formulaires ci-dessous.
  • formSessionIntent (string) - L’intention de formulaire utilisée lors de l’affinage du schéma. Elle applique les valeurs et comportements propres à une intention, comme availableIntents.defaultPage, les champs readonly, les champs hide, les defaultValue de champs et la sélection d’intention des sous-formulaires. L’extension form renderer transmet '*' par défaut; lorsque vous utilisez FormEngine directement, transmettez '*' explicitement si vous voulez le comportement d’intention générique.
  • onSubmit (function) - Fonction de rappel appelée lorsque le formulaire est soumis avec succès. Reçoit un tableau de résultats de processeur. Pour les formulaires qui utilisent EncounterFormProcessor, ces résultats sont les rencontres créées ou mises à jour.
  • onCancel (function) - Fonction de rappel appelée lorsque l’utilisateur annule le formulaire.
  • handleClose (function) - Fonction de rappel appelée lorsque le formulaire doit être fermé.
  • handleConfirmQuestionDeletion (function) - Gestionnaire personnalisé pour confirmer la suppression de questions répétables. Doit retourner une Promise qui se résout lorsque la suppression est confirmée.
  • markFormAsDirty (function) - Fonction de rappel appelée lorsque l’état “dirty” du formulaire change. Utile pour l’intégration dans les espaces de travail pour demander confirmation avant de fermer.
  • hideControls (boolean) - Masquer les boutons d’action du formulaire (Enregistrer, Annuler). Utile pour les vues intégrées ou l’interface utilisateur personnalisée.
  • hidePatientBanner (boolean) - Masquer la bannière patient qui apparaît dans les espaces de travail ultra-larges.
  • preFilledQuestions (Record<string, string | number | Date | boolean | Array<string>>) - Pré-remplir des questions spécifiques avec des valeurs. Les clés sont les IDs des questions, les valeurs sont les valeurs pré-remplies.

Combinaisons de props courantes

Formulaire de base avec UUID :

<FormEngine patientUUID={patientUuid} formUUID={formUuid} />

Modification d’une rencontre existante :

<FormEngine patientUUID={patientUuid} formUUID={formUuid} encounterUUID={encounterUuid} mode="edit" />

Formulaire avec intégration dans un espace de travail :

import React, { useState } from 'react'; import { Workspace2, type Workspace2DefinitionProps } from '@openmrs/esm-framework'; import { FormEngine } from '@openmrs/esm-form-engine-lib'; function MyDirectFormWorkspace({ closeWorkspace, workspaceProps: { patientUuid, formUuid }, }: Workspace2DefinitionProps<{ patientUuid: string; formUuid: string }>) { const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); return ( <Workspace2 title="Mon formulaire" hasUnsavedChanges={hasUnsavedChanges}> <FormEngine patientUUID={patientUuid} formUUID={formUuid} onSubmit={() => closeWorkspace({ discardUnsavedChanges: true })} handleClose={() => closeWorkspace()} markFormAsDirty={setHasUnsavedChanges} /> </Workspace2> ); }

Modes de rendu des formulaires

Le React Form Engine prend en charge quatre modes de rendu, chacun adapté à différents cas d’usage :

Mode Enter (par défaut)

Mode : 'enter' ou undefined

Cas d’usage : Créer de nouvelles entrées de formulaire

Comportement :

  • Le formulaire est rendu en mode lecture-écriture
  • Tous les champs sont modifiables
  • Le formulaire peut être soumis pour créer une nouvelle rencontre
  • Sélectionné automatiquement lorsqu’aucun encounterUUID n’est fourni et que mode n’est pas spécifié
<FormEngine patientUUID={patientUuid} formUUID={formUuid} mode="enter" // ou omettre pour la valeur par défaut />

Mode Edit

Mode : 'edit'

Cas d’usage : Modifier des entrées de formulaire existantes

Comportement :

  • Le formulaire est rendu en mode lecture-écriture
  • Le formulaire est pré-rempli avec les données de la rencontre existante
  • Le formulaire peut être soumis pour mettre à jour la rencontre
  • Sélectionné automatiquement lorsque encounterUUID est fourni et que mode n’est pas spécifié
<FormEngine patientUUID={patientUuid} formUUID={formUuid} encounterUUID={encounterUuid} mode="edit" // ou omettre lorsque encounterUUID est fourni />

Mode View

Mode : 'view'

Cas d’usage : Afficher les données du formulaire en mode lecture seule

Comportement :

  • Le formulaire est rendu en mode lecture seule
  • Tous les champs sont désactivés
  • Le formulaire ne peut pas être soumis
  • L’enregistrement est désactivé ou masqué, et le contrôle fermer/annuler ferme le formulaire
<FormEngine patientUUID={patientUuid} formUUID={formUuid} encounterUUID={encounterUuid} mode="view" />

Mode Embedded View

Mode : 'embedded-view'

Cas d’usage : Afficher les données du formulaire dans un widget ou une carte condensée

Comportement :

  • Le formulaire est rendu en mode lecture seule
  • La navigation latérale et les boutons d’action du bas sont masqués
  • La bannière patient est masquée
  • Les champs transitoires vides, ainsi que les champs vides configurés pour être masqués dans les formulaires en lecture seule, sont omis
  • Mise en page compacte adaptée à l’intégration dans d’autres composants
<FormEngine patientUUID={patientUuid} formUUID={formUuid} encounterUUID={encounterUuid} mode="embedded-view" hideControls={true} />

Gestion de la soumission et de la réponse du formulaire

Lorsqu’un formulaire est soumis, le callback onSubmit reçoit un tableau de résultats de processeur. Pour les formulaires qui utilisent EncounterFormProcessor, chaque résultat est une rencontre créée ou mise à jour.

Gérer la soumission du formulaire

import { type Encounter } from '@openmrs/esm-framework'; function MyFormWorkspace({ patientUuid, formUuid }: Props) { const handleSubmit = (encounters: Array<Encounter>) => { const encounter = encounters[0]; // Gérer la soumission réussie console.log('Rencontre créée :', encounter.uuid); console.log('Observations :', encounter.obs); // Fermer l'espace de travail ou naviguer closeWorkspace({ discardUnsavedChanges: true }); // Actualiser ici les données liées aux rencontres, visites ou espaces de travail. }; return ( <FormEngine patientUUID={patientUuid} formUUID={formUuid} onSubmit={handleSubmit} /> ); }

Gestion des erreurs

Le Form Engine gère automatiquement les erreurs de validation et les affiche en ligne. Le callback onSubmit est appelé uniquement après une soumission réussie. Si la soumission échoue, le Form Engine gère l’erreur en interne et l’affiche à l’utilisateur. Votre callback onSubmit n’est alors pas appelé.

import { type Encounter } from '@openmrs/esm-framework'; function MyFormWorkspace({ patientUuid, formUuid }: Props) { const handleSubmit = (encounters: Array<Encounter>) => { // Ce callback est appelé uniquement si la soumission réussit // Le Form Engine gère les erreurs en interne console.log('Formulaire soumis avec succès :', encounters); closeWorkspace({ discardUnsavedChanges: true }); }; return ( <FormEngine patientUUID={patientUuid} formUUID={formUuid} onSubmit={handleSubmit} /> ); }

Exemple complet : Espace de travail de formulaire

Voici un exemple complet d’un espace de travail de formulaire personnalisé qui s’intègre au dossier patient :

import React, { useMemo, useState } from 'react'; import { ExtensionSlot, Workspace2 } from '@openmrs/esm-framework'; import { useSWRConfig } from 'swr'; import { invalidateVisitAndEncounterData, type FormRendererProps, type PatientWorkspace2DefinitionProps, } from '@openmrs/esm-patient-common-lib'; interface MyFormWorkspaceProps { formUuid: string; encounterUuid?: string; } export function MyFormWorkspace({ closeWorkspace, workspaceProps: { formUuid, encounterUuid }, groupProps: { patient, patientUuid, visitContext, mutateVisitContext }, }: PatientWorkspace2DefinitionProps<MyFormWorkspaceProps, object>) { const { mutate: globalMutate } = useSWRConfig(); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); const state = useMemo( (): FormRendererProps => ({ formUuid, patient, patientUuid, visit: visitContext, visitUuid: visitContext?.uuid, encounterUuid: encounterUuid ?? '', closeWorkspace, closeWorkspaceWithSavedChanges: () => { mutateVisitContext?.(); invalidateVisitAndEncounterData(globalMutate, patientUuid); return closeWorkspace({ discardUnsavedChanges: true }); }, setHasUnsavedChanges, additionalProps: { mode: encounterUuid ? 'edit' : 'enter', }, }), [ formUuid, globalMutate, patient, patientUuid, visitContext, encounterUuid, closeWorkspace, mutateVisitContext, setHasUnsavedChanges, ] ); return ( <Workspace2 title="Mon formulaire" hasUnsavedChanges={hasUnsavedChanges}> <ExtensionSlot name="form-widget-slot" state={state} /> </Workspace2> ); }

Pré-remplir les questions du formulaire

Vous pouvez pré-remplir des questions spécifiques dans un formulaire en utilisant la prop preFilledQuestions :

<FormEngine patientUUID={patientUuid} formUUID={formUuid} preFilledQuestions={{ 'vitals-weight': 70, 'vitals-height': 175, 'chief-complaint': 'Le patient signale un mal de tête' }} />

Les clés dans preFilledQuestions doivent correspondre à la propriété id des questions dans votre schéma de formulaire. Lorsque vous transmettez des valeurs via l’extension form renderer du dossier patient, conservez-les sous forme de chaînes, car son type partagé FormRendererProps limite actuellement preFilledQuestions à Record<string, string>.

Intention de session de formulaire

La prop formSessionIntent sélectionne les comportements propres à une intention dans le schéma de formulaire. Utilisez-la lorsqu’un schéma définit des valeurs par défaut, des champs en lecture seule ou masqués, des pages par défaut ou des comportements de sous-formulaires différents selon les workflows. L’extension form renderer du dossier patient utilise '*' par défaut, mais l’utilisation directe de FormEngine laisse cette valeur vide sauf si vous la transmettez :

<FormEngine patientUUID={patientUuid} formUUID={formUuid} formSessionIntent="VITALS" // Appliquer les comportements du schéma pour l'intention VITALS />

Prochaines étapes

Dernière mise à jour le