Skip to main content

QuestionnaireResponseForm

QuestionnaireForm renders a FHIR Questionnaire as a compound component. It supports paged or all-items layouts, enabled-when conditions, default answers, required-field validation, and either caller-owned submission or the SDK's FHIR QuestionnaireResponse creation.

<QuestionnaireForm
questionnaire={questionnaire}
onSubmit={async (values) => saveValues(values)}
>
<QuestionnaireForm.Header>
<QuestionnaireForm.Header.Title />
<QuestionnaireForm.Header.Subtitle />
</QuestionnaireForm.Header>
<QuestionnaireForm.Content>
<QuestionnaireForm.Content.Item />
<QuestionnaireForm.Content.Error />
</QuestionnaireForm.Content>
<QuestionnaireForm.Navigation>
<QuestionnaireForm.Navigation.PreviousButton />
<QuestionnaireForm.Navigation.NextButton />
<QuestionnaireForm.Navigation.SubmitButton />
</QuestionnaireForm.Navigation>
</QuestionnaireForm>;

Props and submission modes​

questionnaire is required. paged defaults to true; when false, the root is a ScrollView and Content.AllItems is the matching content primitive. The root also accepts the relevant React Native ViewProps/ScrollViewProps, style, and testID.

Choose exactly one submission mode:

  • onSubmit(values, formikHelpers?): the app owns persistence. The callback is async and receives QuestionnaireFormValues; the SDK does not create a FHIR response in this mode.
  • onSuccess(response) and optional onError(error): the SDK gets the active profile from @ovok/core, builds a completed QuestionnaireResponse, adds subject and a stable identifier, and calls createResourceIfNoneExist. This mode requires a configured core client/profile.

The SDK-managed mode assigns a stable identifier and uses createResourceIfNoneExist. The identifier is retained for the form instance, so a second legitimate submission of the same questionnaire can be treated as an existing response. Remount the form or use the app-owned onSubmit mode when repeated submissions are separate records.

initialValues can seed answers. Values are strings, booleans, null, or undefined; the SDK removes disabled conditional answers during validation.

FHIR and UI behavior​

Top-level groups become pages. If the questionnaire has no group items, the SDK creates one synthetic page. In paged mode, one enabled item is shown at a time. In all-items mode, Content.AllItems renders the enabled items in a flat list.

Supported item renderers and response mapping are defined by the current source; common types include boolean, choice, date, dateTime, decimal, integer, string, and text. Conditional items use enableWhen with all or any behavior. answerOption.initialSelected seeds choices when an item becomes active.

Required validation runs before submission and considers only enabled items. Paged navigation also prevents advancing from an unanswered required item.

Compound exports​

Header, Header.Title, Header.Subtitle, Content, Content.Item, Content.AllItems, Content.Error, Navigation, Navigation.PreviousButton, Navigation.NextButton, and Navigation.SubmitButton are exported from the compound root. The form provider and hooks are public for custom layouts; use them only inside the corresponding form context.

useQuestionnaireForm() returns the Formik state plus questionnaire navigation data, errorMessage, submissionError, and retrySubmit(). submissionError is the error message from the latest failed async submission; it may already be a translation key, but arbitrary backend text is not translated automatically. The default Content.Error renders that value through i18next and offers a Try again button when submissionError is present. The onError callback fires for failures from both the SDK-managed FHIR submission path and a custom onSubmit callback.

useQuestionnaireNavigation() returns isCurrentItemRequired, isCurrentItemAnswered, isLastItem, currentItemNumber, totalItems, showPrevious, isSubmitting, handleNext, and handlePrevious. It must be used inside QuestionnaireNavigationProvider, which is normally mounted by QuestionnaireFormProvider.

The remaining public hooks support custom renderers:

  • useQuestionnaireNavigationState(...) calculates the current-item flags and counters when the app owns the navigation provider.
  • useNavigationHandlers(...) returns handleNext and handlePrevious for the current page/item state. Required answers are checked before advancing.
  • useInitialSelectedValues(...) applies FHIR answerOption.initialSelected values and initializes enabled boolean items to null without triggering validation.

QuestionnaireSubmitUtils.createQuestionnaireResponse(responses, pages, questionnaire) creates a completed FHIR QuestionnaireResponse with the questionnaire reference, authored timestamp, and response items. It does not persist the response or add the active patient subject; the SDK-managed submission path adds those app/client-owned fields before saving.

QuestionnaireFormValues, ResponseValues, ExtendedQuestionnaireItem, and the provider/context prop types are public TypeScript exports. The SDK extends FHIR questionnaire items with optional placeholder, helperText, and answerOption.initialSelected fields for rendering.

The SDK supplies layout primitives and FHIR mapping, not a router, persistence policy, analytics policy, or app-specific questionnaire schema.