Skip to main content

Modeling Questionnaires and Responses

Questionnaires are used to organize a collection of questions to gather healthcare information and are modeled in FHIR as a Questionnaire resource. The responses to these questions are modeled with the QuestionnaireResponse resource.

Creating a Questionnaire

A Questionnaire represents the questions, rules for answering the questions, and metadata used to define what it should be used for. It allows you to create complex forms with nested and conditional questions.

ElementDescriptionCode SystemExample
titleA human-readable name to identify the Questionnaire.US Surgeon General - Family Health Portrait
nameA computer-readable name to identify the Questionnaire.USSurgeonGeneralFamilyHealthPortrait
itemAn object containing the questions and groups of questions. Also includes any rules defined for answering.See below
subjectTypeThe resource types that can be a subject of this Questionnaire.Patient
descriptionA description of the Questionnaire. It can include instructions, examples, comments about misuse, etc.Questions to get a picture of family health and family health history.
purposeAn explanation of why the Questionnaire is needed.Captures basic family history information.
statusDefines the stage of its lifecycle a Questionnaire is in (e.g. active, in a draft, etc.).Publication Status Codesdraft

Defining the Questions

The actual questions on a Questionnaire are defined in the item element. This element allows you to structure your questions both as individual questions and in groups. You can also provide additional context or instructions on how the questions should be answered.

One of the most important properties in the item is linkId, which is used to link the questions to the corresponding answers on a QuestionnaireResponse resource. These must all be unique within the Questionnaire to ensure that there is no ambiguity.

PropertyDescriptionExample
linkIdA unique identifier within the Questionnaire that maps directly to the answer for the equivalent item on a QuestionnaireResponse.gender
textThe text of the question or name of a group of questions.What is your date of birth?
typeThe type of item this is. This could be a group, or could refer to the datatype that is used to answer the question.date
itemAnother item used when making groups or nested questions.See below
answerValueSetA reference to an external value set containing possible answers for the question.http://hl7.org/fhir/ValueSet/yesnodontknow
answerOptionAn array of possible answers for the question.
initialA value that will pre-populate a free-form field when the question renders.1970-01-01
initialSelectedA value that will pre-populate the field of an answerOption type question when the question renders.male
requiredA boolean indicating if the question must be answered.false
repeatsA boolean indicating if the question may have more than one associated answer.true
Example: A basic Questionnaire
{
resourceType: 'Questionnaire',
id: 'example-questionnaire',
status: 'draft',
title: 'Patient Health Questionnaire',
description: 'A questionnaire to gather basic health information from the patient',
item: [
{
linkId: 'full-name',
text: 'Patient Full Name',
type: 'string',
required: true,
},
{
linkId: 'age',
text: 'Patient Age',
type: 'integer',
},
{
linkId: 'gender',
text: 'Patient Gender',
type: 'choice',
answerOption: [
{
valueCoding: {
code: 'female',
},
},
{
valueCoding: {
code: 'male',
},
},
],
},
{
linkId: 'medications',
text: 'Current Medications',
type: 'string',
repeats: true,
},
{
linkId: 'allergies',
text: 'Known Allergies',
type: 'string',
repeats: true,
},
{
linkId: 'exercise',
text: 'Weekly Exercise Frequency',
type: 'integer',
},
{
linkId: 'smoking',
text: 'Smoking Status',
type: 'reference',
answerValueSet: 'http://loinc.org/LL22201-3',
},
],
};

Nesting Questions

The item element allows you to group and nest questions together by adding additional sub-questions on the item.item field.

To do this, you must set item.type='group'. This specifies that the item will not be a question, but instead a group of questions. When defining a group, the text property should be a description of the group instead of an actual question.

Example: A Questionnaire with nested questions
{
resourceType: 'Questionnaire',
id: 'nested-questionnaire',
status: 'active',
subjectType: ['Patient'],
item: [
{
linkId: 'allergies',
text: 'Do you have allergies?',
type: 'boolean',
},
{
linkId: 'general',
text: 'General Information',
type: 'group',
item: [
{
linkId: 'general.gender',
text: 'What is your gender?',
type: 'choice',
answerOption: [
{
valueCoding: {
code: 'female',
},
},
{
valueCoding: {
code: 'male',
},
},
],
},
{
linkId: 'general.dob',
text: 'What is your date of birth?',
type: 'date',
},
{
linkId: 'general.marital',
text: 'What is your marital status?',
type: 'choice',
answerOption: [
{
valueCoding: {
code: 'married',
},
},
{
valueCoding: {
code: 'single',
},
},
],
},
],
},
{
linkId: 'intoxicants',
text: 'Intoxicants',
type: 'group',
item: [
{
linkId: 'intoxicants.smoking',
text: 'Do you smoke?',
type: 'boolean',
},
{
linkId: 'intoxicants.alcohol',
text: 'Do you drink alcohol?',
type: 'boolean',
},
],
},
],
};

Defining Rules For Your Questions

FHIR allows you to set rules for your questions beyond just providing options for the answer. The two main rules that you can define are:

  • Setting initial values
  • Conditionally enabling/disabling certain questions

Initial Values

To set an initial value for your question, you can use the item.initial or item.initialSelected field.

The initial property can be set to any value type, but should be the same as the type field of the item it is on. It can be overwritten by the user responding to the Questionnaire, but the value will persist if the user does not change it.

The initialSelected field works in the same way, but applies to questions that have an answerOption field, and is a property on that field (i.e. answerOption.initialSelected). In this case you set an initial choice that is automatically selected when a question renders.

Conditionally Displaying Questions

You can conditionally display questions so that they only appear based on a user's answer to a different question. This is done using the item.enableWhen field. The enableWhen property is an object with properties that define when a question should be displayed.

PropertyDescriptionCode SystemExample
questionThe linkId for the item whose answer determines if this item will appear.gender
operatorThe criteria used to determine if the question will appear.Questionnaire Item Operator=
answer[x]The value that the referenced question is being tested against using the operator. The datatype should match the answer datatype of the referenced question.female
Example: A Questionnaire with initial values and conditionally rendered questions
{
resourceType: 'Questionnaire',
id: 'conditional-questionnaire',
status: 'active',
subjectType: ['Patient'],
item: [
{
linkId: 'allergies',
text: 'Do you have allergies?',
type: 'boolean',
},
{
linkId: 'general',
text: 'General Information',
type: 'group',
item: [
{
linkId: 'general.gender',
text: 'What is your gender?',
type: 'choice',
answerOption: [
{
valueCoding: {
code: 'female',
},
},
{
valueCoding: {
code: 'male',
},
},
],
},
{
linkId: 'general.dob',
text: 'What is your date of birth?',
type: 'date',
},
{
linkId: 'general.birth-country',
text: 'What is your country of birth?',
type: 'string',
initial: [
{
valueString: 'United States',
},
],
},
{
linkId: 'general.marital',
text: 'What is your marital status?',
type: 'choice',
answerOption: [
{
valueCoding: {
code: 'married',
},
},
{
valueCoding: {
code: 'single',
},
},
],
},
],
},
{
linkId: 'intoxicants',
text: 'Intoxicants',
type: 'group',
item: [
{
linkId: 'intoxicants.smoking',
text: 'Do you smoke?',
type: 'boolean',
},
{
linkId: 'intoxicants.alcohol',
text: 'Do you drink alcohol?',
type: 'boolean',
},
],
},
{
linkId: 'pregnancy',
text: 'Pregnancy History',
type: 'group',
item: [
{
linkId: 'pregnancy.boolean',
text: 'Have you ever been pregnant?',
type: 'boolean',
},
{
linkId: 'pregnancy.count',
text: 'How many times have you been pregnant?',
type: 'integer',
enableWhen: [
{
question: 'pregnancy.boolean',
operator: '=',
answerBoolean: true,
},
],
},
],
enableWhen: [
{
question: 'general.gender',
operator: '=',
answerCoding: {
code: 'female',
},
},
],
},
],
};

Creating a Response to a Questionnaire

Once you have created your Questionnaire, you will need to record responses to it. This is modeled with the QuestionnaireResponse resource.

Each QuestionnaireResponse represents an individual response to a Questionnaire. An individual response could be one response per person or the same person responding multiple times to the same Questionnaire over the course of their care.

A QuestionnaireResponse should link to a specific Questionnaire. It does not necessarily need to provide answers to each question, but all required questions must be answered.

Structuring Answers

The answer items in a QuestionnaireResponse should follow the same structure in terms of grouping and nesting and adhere to all data types for answers defined in the linked Questionnaire.

The QuestionnaireResponse resource provides fields to define meta data about the responses, such as who provided the answers, recorded the answers, and more.

ElementDescriptionCode SystemExample
questionnaireThe canonical URL of the Questionnaire that is being answered by this response.http://example.org/Questionnaires/example-questionnaire
sourceThe individual who provided the answers on this response.Patient/homer-simpson
subjectWho/what the answers from the response apply to, but not necessarily who actually answered the questions.Patient/maggie-simpson
itemThe responses to the questions.See below
authorThe individual who received and recorded the responses, but not necessarily who actually answered the questions.Practitioner/receptionist
authoredThe date that the answers were gathered.dateTime2023-11-18
encounterA reference to the Encounter that the response is a part of.Encounter/maggie-simpson-physical

Answering the Questions

The answers on a QuestionnaireResponse are stored in the item element. It is very similar to the item element on a Questionnaire, allowing you to model the responses so that they match the structure of the Questionnaire they are answering.

PropertyDescriptionExample
answer.value[x]The answer to the question. The datatype should correspond to what is specified in the Questionnaire.itemfemale
answer.itemAny nested answers or groups within the current one. Only used when nesting underneath an answer.
textThe text of the question that is being answered.What is your gender?
itemAn additional item that allows for grouping or nesting answers.
linkIdThe item from the corresponding Questionnaire that this answer responds to.marital-status
Example: A QuestionnaireResponse responding to the conditional questionnaire above
{
resourceType: 'QuestionnaireResponse',
id: 'homer-simpson-conditional-response',
status: 'completed',
questionnaire: 'http://example.org/Questionnaires/conditional-questionnaire',
subject: {
reference: 'Patient/homer-simpson',
},
author: {
reference: 'Patient/homer-simpson',
},
authored: '2023-11-18',
source: {
reference: 'Patient/homer-simpson',
},
item: [
{
linkId: 'allergies',
text: 'Do you have allergies?',
answer: [
{
valueBoolean: false,
},
],
},
{
linkId: 'general',
text: 'General Information',
item: [
{
linkId: 'general.gender',
text: 'What is your gender?',
answer: [
{
valueCoding: {
code: 'M',
},
},
],
},
{
linkId: 'general.dob',
text: 'What is your date of birth?',
answer: [
{
valueDate: '1956-05-12',
},
],
},
{
linkId: 'general.birth-country',
text: 'What is your country of birth?',
answer: [
{
valueString: 'United States',
},
],
},
{
linkId: 'general.marital',
text: 'What is your marital status?',
answer: [
{
valueCoding: {
code: 'married',
},
},
],
},
],
},
{
linkId: 'intoxicants',
text: 'Intoxicants',
item: [
{
linkId: 'intoxicants.smoking',
text: 'Do you smoke?',
answer: [
{
valueBoolean: true,
},
],
},
{
linkId: 'intoxicants.alcohol',
text: 'Do you drink alcohol?',
answer: [
{
valueBoolean: true,
},
],
},
],
},
],
};

UI Components

Medplum provides React components to help you view and build Questionnaire resources. You can preview the QuestionnaireForm and QuestionnaireBuilder components in Storybook.