2.7.0 - STU 3 (2nd ballot)

This page is part of the Structured Data Capture FHIR IG (v2.7.0: STU 3 Ballot 2) based on FHIR R4. The current version which supercedes this version is 3.0.0. For a full list of available versions, see the Directory of published versions

Advanced form behavior and calculation

Simple questionnaires only need simple behavior. The order of the questions is fixed, all of them get displayed and the only controls that need to be specified are what the types of the questions are, whether a group or the answers to a question repeats, and whether a group or a question must be answered. However, for more sophisticated forms, there may be a need to set default answers, to enforce rules around the allowed answers (such as length, size, types of references), and/or to make the behavior of the questionnaire dynamic based on previous answers. The FHIR specification provides core elements that allow some of these things, and common extensions for others. This implementation guide supplements with even more extensions. It also defines the sdc-questionnaire-behave profile to highlight what extensions are available and where they are intended to be used. It also identifies specific 'must support' extensions that systems that claim to support SDC rendering SHALL be capable of authoring and/or rendering, as befits the CapabilityStatement(s) they claim conformance to.

Element and Overview

The following sub-sections describe the different core elements and extensions available to control the 'behavior' of a questionnaire. Each extension includes the following information:

  • Code: This is the name of the core element or the unique label for the extension. The extension label appears at the end of the URL of the 'source' (below). In this implementation guide, extensions are generally just referred to by their code.
  • Source: This will either 'N/A', 'Core', 'Questionnaire' or 'SDC'. 'N/A' indicates that the element is part of the core spec, not an extension. 'Core' indicates that the extension is defined in the core specification and is not specific to the Questionnaire resource. The base URL for 'core' extensions is http://hl7.org/fhir/StructureDefinition/. Questionnaire indicates an extension defined in the core specification that is specific to Questionnaires. The base URL for 'Questionnaire' extensions is http://hl7.org/fhir/StructureDefinition/questionnaire-. SDC extensions are defined within this implementation guide. Their base URL is http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-
  • Location: This indicates where the element or extension can appear. Possible values are 'root' (for those that appear directly on the Questionnaire element), 'item' (for those that can appear on any type of item) or 'question' for those that can only appear on question items. In some cases, additional restrictions/guidance will be provided
  • Data Type: Indicates what content the element or extension can have.

Both core elements and extensions will have explanatory text that provides additional guidance on how the extension is used.

Value constraints

These elements all constrain the allowed values for answers to Questionnaires.

Code Source Location Data Type
maxLength Core question integer

This core element is typically used with strings, but can theoretically be used for other variable-length simple types (e.g. to limit the maximum precision of a 'time' element). It SHALL NOT be used for complex types such as choice, open-choice, quantity, attachment or reference. It establishes the maximum length of the answer in characters. Be aware that in UTF-8, some characters may take multiple bytes, so maxLength does not place a specific constraint on the maximum number of bytes. If not specified, the maximum length is established by the data type. (For example, in FHIR the 'string' data type has a maximum character length of 1 megabyte (2^20).)

This element SHALL be greater than or equal to the value of minLength if both are specified. If set to a value greater than the inherent maximum length of the data type (e.g. 10 for date), the extension will be ignored.

minLength Core question integer

This extension allows setting a minimum length for answers with a simple type. Like maxLength, it can only be used on simple types, not choice, open-choice, quantity, attachment or reference. It is typically used on strings to help ensure a minimum amount of detail is provided. However, it can also be used to set a minimum precision for variable-length types such as date or time. E.g. to enforce that a date includes at least the year and month, the minimum length could be set to 7.

This element SHALL NOT be greater than the value of maxLength if both are specified, or greater than the maximum permitted length for the FHIR simple type if not specified. (For example, the maximum length of date is 10, so a minLength of 11 on a question with an item.type of 'date' would be an error.)

regex Core question string

This allows checking that an extension adheres to a regular expression. For example, enforcing the ANA NAN syntax of a Canadian postal code. The regular expression SHALL adhere to the same requirements as defined for the FHIRPath matches operation. Also see the entryFormat which might be a good way of displaying the desired format to the user. (For example, 'ANA NAN' which can be conveyed using 'entryFormat' is more intuitive for most users than seeing the actual regex (\d[A-Z]\d [A-Z]\d[A-Z]).

minValue Core date, dateTime, time, decimal, integer as per question type

This extension is used for questions with simple quantitative types. It does not currently support the Quantity data type. The extension allows establishing the lower bound for an answer. For example, ensuring that birth dates are >= 1990-01-01 or an integer is greater than or equal to 0. (Note that the integer and decimal types both allow negative numbers if not constrained.) This extension can be used together with the cqf-calculatedValue extension to establish a dynamic limit. For example, ensuring that a date of birth will result in a maximum age by setting minValue with an expression of 'today() - 18 years'.

The minValue SHALL be less than or equal to the maxValue, if both are specified.

maxValue Core date, dateTime, time, decimal, integer as per question type

This extension is used for questions with simple quantitative types. It does not currently support the Quantity data type. The extension allows establishing the upper bound for an answer. For example, ensuring that birth dates are >= 1990-01-01 or an integer is greater than or equal to 0. (Note that the integer and decimal types both allow negative numbers if not constrained.) This extension can be used together with the cqf-calculatedValue extension to establish a dynamic limit. For example, ensuring that a date of birth will result in a minimum age by setting maxValue with an expression of 'today() - 18 years'.

The minValue SHALL be less than or equal to the maxValue, if both are specified.

maxDecimalPlaces Core decimal integer

For decimal types, this indicates the maximum precision below the decimal. For example, limiting a dollar amount to 2 decimal places.

mimeType Core attachment code

When capturing attachments, this allows constraining the mime type of the attached data. Multiple repetitions can be specified to allow more than one candidate type. For example, if the attachment is intended to be an image, repetitions of this extension could constrain attachments to be image/jpeg, image/png or image/bmp.

maxSize Core Attachment decimal

This extension is also used for questions with type of 'attachment'. It allows specifying an upper bound on the size of the attachment in bytes. This can help ensure that data embedded in the QuestionnaireResponse is 'manageable' and that a user doesn't accidentally attach a photo, document or something else that's unreasonably large (10s of megabytes or more).

Choice Restriction

These elements constrain what choices are available as well as how many answers can be/must be specified.

Code Source Location Data Type
answerOption Core question integer, date, time, string, Coding, Reference

This allows constraining the allowed value for a question item's answer to an enumerated set. Each answerOption repetition indicates one of the possible allowed values. The answer to the question, if answered, SHALL match one of the specified repetitions unless the item.type is open-choice. The type of the answerOption must match the type of the question. (Coding is used for both choice and open-choice.)

There are two mechanisms to enumerate the permitted answers for a question: this element and the answerValueSet element. answerValueSet only supports defining values for 'string' and Coding elements. (For 'string', the allowed values are those found in the value set expansion's 'code' elements.) However, it allows for the set of allowed codes to be maintained as an expression such as "all medications from SNOMED CT", automatically adjusting as the set of matching codes changes based on the evolution of the code system. As such, answerValueSet is appropriate when the set of codes is large or potentially dynamic and enumerating all the possible choices within the Questionnaire doesn't make sense. To have tighter control of the set of answers allowed for the question, consider making the reference to the ValueSet version-specific. To really lock down the set of codes, the value set should itself tie itself to specific versions of the underlying code systems and/or specify a lockedDate.

answerValueSet also allows for the possibility of sharing a set of answers across multiple questions within a single Questionnaire. Sharing the set of allowed answers simplifies maintenance and ensures consistency across questions. This can be important when representing choices as columns or rows in a table (see itemControl. If appropriate, the ValueSet can be nested inside the Questionnaire as a contained resource. This should only be done if the ValueSet is intrinsically tied to the Questionnaire and should only ever be edited in the context of the Questionnaire. Such ValueSets will not be available for use elsewhere.

answerOption works well when there is a small (2 - 20ish) number of choices. It's the only option if the question type is integer, date, time or reference. The set of options is maintained independently for each question.

answerOption and answerValueSet are mutually exclusive. They SHALL NOT appear together on the same question. If answerOption appears, there SHOULD be more than one repetition of it. A question with a single answerOption will be treated as having a single fixed value.

If the set of choices is restricted using either answerOption or answerValueSet, the use of any other Value Constraint elements is redundant and confusing. Therefore, questions that have either 'answerOption' or 'answerValueSet' SHALL NOT make use of any of the other Value Constraint extensions.

answerValueSet Core question integer

See discussion above under answerOption.

required Questionnaire group, question boolean

For an 'active' (see enableWhen) group or question, this indicates whether the element must appear in the corresponding QuestionnaireResponse. If 'true', it means that at least one answer must be provided for the question, or for a group, that at least one question descended from the group must have an answer. Note that if a group is not included, there's no need to include items within the group, even if they are marked as 'required'. Display items should never be marked as 'required' and if they are, it has no meaning. This element can also impact rendering. To further constrain the minimum number of elements required, see the minOccurs extension.

Note that, depending on entryMode, users may be able to 'skip' required questions and come back to them later. However, the status of a QuestionnaireResponse cannot change to 'completed' until all enabled 'required' items are populated.

repeats Questionnaire group, question boolean

For groups, a 'repeats' value of 'true' means that the QuestionnaireResponse can contain multiple item repetitions that correspond to the same linkId. For questions, it means that the question with the same linkId can have more than one answer. (I.e. there won't be multiple repetitions of the question item in the QuestionnaireResponse, but instead the one corresponding question item can have multiple answers. Display items should never be marked as 'repeats' and if they are, it has no meaning. This element can also impact rendering. To constrain the minimum number of elements permitted for a repeating element, see the minOccurs extension.

readOnly Questionnaire question boolean

If present indicates that the answer to the question is not allowed to be edited or changed by someone completing the questionnaire. This can be used for information that is either set to a fixed value by the form designer using the initial element or something that is calculated using the initialExpression during load or calculatedExpression based on other information in the QuestionnaireResponse. This element can also impact rendering. Elements marked as 'readOnly' are intended to be displayed to the user filling out the QuestionnaireResponse. For information that should not be seen by the user, use the hidden extension.

minOccurs Questionnaire group, question integer

The required element allows distinguishing items that are optional (minOccurs=0) from those that are required (minOccurs=1). However, for elements where repeats is true, it's sometimes necessary to indicate that multiple repetitions are required. For example, a question might ask the user to "select your top 3 choices" and want to enforce that at least 3 choices had been chosen. The minOccurs extension allows such rules to be enforced. Using the cqf-calculatedValue extension, the minimum number of repetitions can also be made dynamic. For example, one question might ask "How many brothers and sisters did you have?" while a subsequent repeating group captures information about each sibling. The Questionnaire could enforce that the number of group repetitions matched the number of siblings indicated by setting minOccurs and maxOccurs.

This element SHALL only be set for an item where both required and repeats are true.

Note that, depending on entryMode, users may be able to 'skip' questions that do not meet the minimum number of repetitions and come back to them later. However, the status of a QuestionnaireResponse cannot change to 'completed' until all enabled items have their minOccurs requirement met.

maxOccurs Questionnaire group, question integer

The repeats element allows indicating that an item is permitted to repeat, but places no limits on the number of times the group can appear in the response or the number of answers a question can have. This extension allows a limit to be imposed. For example, a question might indicate "choose no more than 3". Using the cqf-calculatedValue extension, the maximum number of repetitions can also be made dynamic as described in maxOccurs.

This element SHALL only be set for an item where repeats are true.

unitOption Questionnaire Quantity Coding

Just as the answerOption and answerValueSet elements support identifying the specific answers that can be selected, the unitOption and unitValueSet extensions allow defining the choices for the unit of for a question with the 'quantity' type. The behavior and trade-offs between enumerating the options and referencing a re-useable value set are the same for enforcing units as they are for enforcing answer choices and the extensions for units work the same way as those core elements.

To set a default from among the candidate units, it's possible to use the initial element

unitValueSet Questionnaire Quantity Reference(ValueSet)

See unitOption for discussion.

questionnaire-referenceResource Questionnaire Reference code

Questions with a type of 'Reference' have no constraints on what the reference is expected to point to. This extension allows constraining the content to only resources of a specific type. If multiple extensions are present, it indicates that the resource must come from one of them. Further constraining can be done with the referenceProfile and/or referenceFilter extensions.

referenceProfile Questionnaire Reference canonical(StructureDefinition)

This extension asserts that resources selected as the answer to the question must be valid against the specified profile. It is tighter than the referenceResource extension (and thus there's no need to specify a referenceResource if referenceProfile is defined. If multiple referenceResources are listed, then the selected resource must be valid against at least one of the profiles. The Form Filler can choose to use the profiles as filter criteria in a search, but not all systems will necessarily support search by profile or will support the listed profile(s). Thus, a fallback to evaluating candidates against the profile(s) and filtering the list to exclude those that are not should also be supported. More sophisticated querying is supported by the referenceFilter extension.

referenceFilter Questionnaire Reference string

This defines a generic (or occasionally specific) query that can be used to identify the resources that can be returned as answers to the question listing the extension. The query works as per the x-fhir-query mechanism defined on the Using Expressions page. As such, it can take advantage of launchContext, variables and calculatedExpressions to act as part of the query search parameters (for example, limiting responses to those matching a specific patient, those falling within a time range based on the current data, etc.

If a full URL is specified as the base for the query, then the query will be against the specified server. Otherwise it will be against the server managed by the Form Filler or against another server (or set of servers) chosen by the Form Filler. This extension can be supplemented by the referenceProfile extension to further narrow candidate resources returned by the filter.

As a side note, when editing a QuestionnaireResponse, it's possible that the currently selected answer for a question will no longer meet the filter criteria and/or target profile(s). In some cases, it might even have been deleted. The previously selected answer should remain as a valid selection in the choice even if the item has changed at least until the QuestionnaireResponse is stored/saved again.

lookupQuestionnaire Questionnaire Reference canonical(Questionnaire)

In some cases, the target resource for the answer to a Reference question might not exist and the user might need to create it. This can be done by displaying a Questionnaire that supports defining the content of the target resource and using the Data Extraction mechanism to convert the resulting QuestionnaireResponse into a FHIR resource of the appropriate type. The resulting resource can either be stored on the target server or passed as a contained resource within the referencing QuestionnaireResponse. This extension defines the Questionnaire that should be used for the purpose of creating the necessary resource. When this is done, the Questionnaire should be designed such that the resulting resource instance will comply with any declared referenceProfile.

Calculations

These extensions support performing calculations as part of completing a QuestionnaireResponse. This might be to set the value of a readOnly question using calculatedExpression. They can also set the value of other control fields, such as minValue, maxValue, minOccurs or maxOccurs They are all described in detail on the Using Expressions page. They are summarized here to indicate their use as part of defining form behavior. Many of these extensions are also relevant when performing Questionnaire Population and/or Data Extraction.

Code Source Location Data Type
cqf-library Core root canonical(Library)

Described in detail here. This extension allows the expressions-based extensions below to leverage shared libraries of FHIR queries, CQL and FHIRPath.

launchContext SDC root complex

Described in detail here. This extension allows the Questionnaire to be passed context information that can be used within lookupQuestionnaires, to determine which items to enable using enableWhenExpression (e.g. suppress certain questions if the submitter is a specified gender or age), or to help determine the answer to a question, though that falls more within the space of Questionnaire Population.

variable Core root, item Expression

Described in detail here. This extension allows the calculation of information based on descendant question answers (and other variables or launchContext elements) that can then be referenced by extensions on other items that don't have the same scope - and thus don't have access to the same question answers.

initialExpression SDC question Expression

Described in detail here. This extension allows the initial value of an element to be set based on an expression. For example, defaulting a date to the current date. (It can also be used to set an answer based on launch context or information queried from external sources, though that falls more within the domain of Questionnaire Population.)

calculatedExpression SDC question Expression

Described in detail here. This extension allows answers to questions (generally readOnly or hidden ones) to be calculated based on answers to other questions. For example, the determination of a score.

cqf-calculatedValue Core minOccurs, maxOccurs, minValue, maxValue string

This extension can make some of the control values of the Questionnaire dynamic. For the SDC implementation guide, the recommended locations for use are minOccurs, maxOccurs, minValue, and maxValue. However, in principle, they can be used for other elements as well. Even the text of a question could be dynamic, though obviously that could impact the consistency and comparability of data calculated using the Questionnaire.

Other Control

These are additional elements and extensions relevant to controlling the completion of the QuestionnaireResponse that don't fit into the previous categories.

Code Source Location Data Type
entryMode SDC Questionnaire code

This indicates how the questions in the form should be displayed to the user and what type of navigation control they should have to look at (and change) other questions:

  • Only one question displayed at a time; no back-tracking or editing prior questions
  • Backtracking and editing is allowed, but future questions are only enabled once a question has been answered (or explicitly skipped)
  • All enabled questions are displayed at once and the user can fill things in in whatever order they see fit
initial N/A item complex

Establishes the default answer for a question. If the user does not change the value, this is what will appear in the completed QuestionnaireResponse

Note that 'initial' doesn't have to specify all properties. For example, it can be used to select a default unit of measure for a quantity, or potentially (depending on user interface), a default media type for an attachment. To do this, simply specify the property being defaulted (e.g. Quantity.code and Quantity.system) while omitting the remainder.

enableWhen N/A item complex

This controls which questions, groups and even display items should be displayed based on answers to other questions within the response. An item is 'enabled' based on whether the referenced questions have one (or more) of the answers as specified by the enableWhen element. If multiple enableWhen elements are present on an item, the interpretation is governed by the enableBehavior element. Elements that are not enabled should either be hidden from the user or at least grayed-out and non-selectable and non-editable. Any behavioral constraints associated with non-enabled elements (such as required or minOccurs are ignored and no answers are stored for non-enabled content.

For more sophisticated enableWhen behavior, the enableWhenExpression element can be used instead.

enableBehavior N/A item code

This determines the interpretation of multiple enableWhen elements. If set to 'all', then the item will only be enabled if all the enableWhen conditions are met. If set to 'any', the item will be enabled if any of the enableWhen conditions are met.

enableWhenExpression N/A item code

This serves the same purpose as enableWhen (and is mutually exclusive with it). It controls whether an item should be 'enabled' or not, but can handle more sophisticated circumstances than that extension. (If enableWhen can meet the need, it should be used instead as it will be more broadly supported.) Specifically, enableWhen allows more complex logic such as a mixture of 'and' and 'or' relationships amongst conditions (e.g. "Enable if Q1=5 and either Q2 or Q3 are true"). It also allows for logic to be based on calculations across questions (possibly leveraging variable) or even based on values passed in by launchContext or queried from outside the questionnaire (see Using Expressions.

usageMode Questionnaire item code

This extension is similar to enableWhen in that it enables or disables elements within the Questionnaire. However, rather than being driven by data within the form or queried or passed from outside, it is instead driven by how the QuestionnaireResponse is being used. Specifically, it allows certain elements to be enabled or disabled based on whether the form is being completed or whether it's being rendered after being completed. When being rendered after completion, it also allows questions and groups to be suppressed if they are 'empty'. For example, the extension might hide data entry instructions when displaying a completed form and might hide 'interpretation' instructions when performing data entry. It might also hide a score during data entry, but make it visible once the form is ready to be reviewed.

constraint Questionnaire item complex

This allows assertion of constraints across an entire questionnaire or across any item with child items. For example, it could be used to require that either the patient identifier or birth date must be specified, that at least 6 of the questions from question 10 through 20 must be answered, or that the sum of questions 1 through 5 must equal exactly 100. The expression is written in FHIRPath and has access to the additional FHIRPath capabilities defined in Using Expressions.

endpoint SDC root uri

This allows a Questionnaire to indicate the URL of the Form Receiver it should be posted to when complete. (Note that it is up to the Form Filler and/or the user to determine whether to post to the indicated endpoint or to store the form elsewhere - or to do both.)

signatureRequired Questionnaire root, group, question CodeableConcept

This allows a form to indicate whether the form must be signed on completion or whether specified questions or answers themselves must be signed. Signature can be as simple as providing the user's initials to confirm that they've verified and agree with the answer, or it could mean a full digital signature. This extension will tend to be used on Questionnaires that result in legal documents.

ordinalValue Core Coding, Questionnaire.item.answerOption, CodeSystem.concept, ValueSet.compose.include.concept decimal

This extension allows a choice element (whether in a question-specific answerOption or in the code system and value set pointed to by answerValueSet) to have an associated numeric weighting. This numeric weighting can be captured as part of the QuestionnaireResponse.item.answer.valueCoding. More importantly it can be referenced by expressions used to calculate scores using calculatedExpression and/or to control the display of elements using enableWhenExpression. For example, the answer 'never' might have an ordinal value of 0, the answer occasionally might have a value of 1, the answer of weekly 2 and daily 4. The answer given would then be incorporated in an overall risk or diagnostic score.