---
description: Populate FHIR Questionnaires with patient data, observations, allergies, and previous form responses using FHIRPath expressions.
---

# How to: Populate forms with data

## Warn

### You should have items with types - that corresponds populate values types.

In all populate items configuration you should use proper item(widget) for populate data

| Item               | data type     |
| ------------------ | ------------- |
| String Input       | string        |
| Textarea           | string        |
| URL                | url           |
| Integer Input      | integer       |
| Decimal Input      | decimal       |
| Quantity Input     | quantity      |
| Date               | date          |
| Time               | time          |
| Datetime           | dateTime      |
| Choice Input       | coding        |
| Open Choice Input  | coding/string |
| Radio Button       | coding        |
| Boolean input      | boolean       |
| File               | attachment    |
| Author's Signature | attachment    |
| Reference          | reference     |

## How to populate form with patient demographic data: patient name, DOB, MRN, address, phone

To populate a form we should:

1. setup a form to be able to get patient's data and prefill form items with it (design time)
2. provide patient's reference to population operation. (usage time)

### Form Setup (design time)

Assume that we already have:

* form with 5 items(data: patient name, DOB, MRN, address, phone)
* Patient resource in the Aidbox DB

Questionnaire example:

```
---
resourceType: Questionnaire
title: Patient demographics
status: draft
url: http://forms.aidbox.io/questionnaire/patient-demographics
item:
- linkId: patient-name
  type: string
  text: Patient Name
- linkId: dob
  type: date
  text: Date of Birth
- linkId: mrn
  type: string
  text: MRN
- linkId: address
  type: text
  text: Address
- linkId: phone
  type: string
  text: Phone Number
```

Patient resource example:

```yaml
resourceType: Patient
id: example
gender: male
name:
- family: Chalmers
  given:
  - Peter
  - James
address:
- city: PleasantVille
  district: Rainbow
  postalCode: '3999'
  text: 534 Erewhon St PeasantVille, Rainbow, Vic  3999
  line:
  - 534 Erewhon St
  state: Vic
identifier:
- use: usual
  type:
    coding:
    - system: http://terminology.hl7.org/CodeSystem/v2-0203
      code: MR
  system: urn:oid:1.2.36.146.595.217.0.1
  value: '12345'
birthDate: '1974-12-25'
telecom:
- system: phone
  value: (03) 5555 6473

```

> WARN: You should have items with types - that corresponds populate values types. (see [WARN section](how-to-populate-forms-with-data.md#warn))

We should setup items with `populate` expressions.

> How to find population expression:
>
> 1. select widget in the outline 2 click on `populate` checkbox in the widget settings panel
> 2. in opened section select `Expression` tab

For this example we will use:

* `%subject` parameter, which will contain `Patient` resource
* `FHIRPath` expressions to retrieve data.

> `%subject` parameter will be filled with data in population operation

#### Expressions:

Patient name

```fhirpath
%subject.name.family + ' ' + %subject.name.given.first()
```

DOB (Date widget)

```fhirpath
%subject.birthDate
```

MRN (Text widget)

```fhirpath
%subject.identifier.where(type.coding.system='http://terminology.hl7.org/CodeSystem/v2-0203', type.coding.code='MR').value
```

address (Text widget)

```fhirpath
%subject.address.text
```

phone (Text widget)

```fhirpath
%subject.telecom.value
```

At the end you should get Questionnaire like this:

```yaml
---
resourceType: Questionnaire
title: Patient Demographics
status: draft
url: http://forms.aidbox.io/questionnaire/patient-demographics
item:
- linkId: patient-name
  type: string
  text: Patient Name
  extension:
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression
    valueExpression:
      language: text/fhirpath
      expression: "%subject.name.family + ' ' + %subject.name.given.first()"
- linkId: dob
  type: date
  text: Date of Birth
  extension:
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression
    valueExpression:
      language: text/fhirpath
      expression: "%subject.birthDate"
- linkId: mrn
  type: string
  text: MRN
  extension:
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression
    valueExpression:
      language: text/fhirpath
      expression: "%subject.identifier.where(type.coding.system='http://terminology.hl7.org/CodeSystem/v2-0203',
        type.coding.code='MR').value"
- linkId: address
  type: text
  text: Address
  extension:
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression
    valueExpression:
      language: text/fhirpath
      expression: "%subject.address.text"
- linkId: phone
  type: string
  text: Phone Number
  extension:
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-initialExpression
    valueExpression:
      language: text/fhirpath
      expression: "%subject.telecom.value"

```
### Populate Parameters (usage time)

To make `%subject` resource available we should call `$populate` operation with specific parameters

* `subject = <reference>` (reference to patient)
* `local = true` (says that we should search for subject in DB and load resource)

Operation call example:

```yaml
POST /fhir/Questionnaire/<qid>/$populatelink

resourceType: Parameters
parameter:
- name: subject
  valueReference:
    reference: Patient/example
- name: local
  valueBoolean: true
```

You should get a link to a new QuestionnaireResponse, that will look like this

```yaml
resourceType: QuestionnaireResponse
questionnaire: http://forms.aidbox.io/questionnaire/patient-demographics
status: in-progress
subject: {reference: Patient/example}
item:
- linkId: patient-name
  text: Patient Name
  answer:
  - {valueString: Chalmers Peter}
- linkId: dob
  text: Date of Birth
  answer:
  - {valueDate: '1974-12-25'}
- linkId: mrn
  text: MRN
  answer:
  - {valueString: '12345'}
- linkId: address
  text: Address
  answer:
  - {valueString: '534 Erewhon St PeasantVille, Rainbow, Vic  3999'}
- linkId: phone
  text: Phone Number
  answer:
  - {valueString: (03) 5555 6473}
```

## How to populate form with patient weight, height

To populate a form we should:

1. setup a form to be able to get patient's observations (design time)
2. provide patient's reference to population operation. (usage time)

### Form Setup (design time)

Assume that we have:

* Form with `body weight` and `body height` items
* Patient in DB
* Patient's `body weight` and `body height` `Observations` in DB

> WARN: You should have items with types - that corresponds populate values types. (see [WARN section](how-to-populate-forms-with-data.md#warn))

Stored `Observations` should be linked to a patient and should be coded with right terminology code (LOINC in our example)

LOINC coding for body measurements:

* Body Height: `{ system: http://loinc.org, code: 8302-2 }`
* Body Weight: `{ system: http://loinc.org, code: 29463-7 }`


Questionnaire example 

```yaml
resourceType: Questionnaire
title: Body Measurements
status: draft
url: http://forms.aidbox.io/questionnaire/body-measurements
item:
- linkId: body-height
  type: quantity
  text: Body Height
  extension:
  - url: http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption
    valueCoding:
      display: cm
- linkId: body-weight
  text: Body Weight
  type: quantity
  extension:
  - url: http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption
    valueCoding:
      display: kg
```


Observation examples

Body Weight

```yaml
resourceType: Observation
subject:
  reference: Patient/example
status: final
code:
  coding:
  - code: 29463-7
    system: http://loinc.org
effectiveDateTime: 2025-12-10T00:00:00   --- Put here dateTime curresponding to current month. This date will be used for quering period.
valueQuantity:
  unit: kg
  value: 80
```

Body Height

```yaml
resourceType: Observation
subject:
  reference: Patient/example
status: final
code:
  coding:
  - code: 8302-2
    system: http://loinc.org
effectiveDateTime: 2025-12-10T00:00:00   --- Put here dateTime curresponding to current month. This date will be used for quering period.
valueQuantity:
  unit: cm
  value: 180
```

We should configure items with Observation based population

1. Select item in outline
2. Press `include code?` section and type corresponding code/system (from Observations)
3. Enable `Populate` section (`Observation` population should be opened by default) and choose period to search for Observations. (For example `1 Month`)

You should get next questionnaire:

```yaml
resourceType: Questionnaire
title: Body Measurements
status: draft
url: http://forms.aidbox.io/questionnaire/body-measurements
item:
- linkId: body-height
  text: Body Height
  type: quantity
  code:
  - code: 8302-2
    system: http://loinc.org
  extension:
  - url: http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption
    valueCoding:
      display: cm
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod
    valueDuration:
      code: mo
      system: http://unitsofmeasure.org
      value: 1
- linkId: body-weight
  type: quantity
  text: Body Weight
  code:
  - code: 29463-7
    system: http://loinc.org
  extension:
  - url: http://hl7.org/fhir/StructureDefinition/questionnaire-unitOption
    valueCoding:
      display: kg
  - url: http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-observationLinkPeriod
    valueDuration:
      code: mo
      system: http://unitsofmeasure.org
      value: 1
```

### Populate parameters (usage time)

To pass Patient's reference we use `subject` parameter to `$populatelink`/`$populate` operation.

Operation call example:

```yaml
POST /fhir/Questionnaire/<qid>/$populatelink

resourceType: Parameters
parameter:
- name: subject
  valueReference:
    reference: Patient/example
```

In a result you will get a link to QuestionnaireResponse with pre-populated data:

```yaml
resourceType: Parameters
parameter:
- name: response
  resource:
    resourceType: QuestionnaireResponse
    questionnaire: http://forms.aidbox.io/questionnaire/body-measurements
    status: in-progress
    subject: {reference: Patient/example}
    item:
    - linkId: body-height
      text: Body Height
      answer:
      - valueQuantity: {unit: cm, value: 180}
    - linkId: body-weight
      text: Body Weight
      answer:
      - valueQuantity: {unit: kg, value: 80}
```

## How to populate form with patient allergies

To populate a form with data from allergies we should

1. setup a form to be able to find allergies for a patient and populate them in a list (design time)
   * Create a `group`/`group table` with columns of proper types
   * Set `named expression` for created `group` to search for allergies
   * Set columns `populate expressions` to extract data from found `AllergyIntolerance` resources
2. provide `Patient` reference in input parameters of populate operation (usage time)

### Form Setup (design time)

Assume that we already have:

* Form for Allergies
* Several `AllergyIntolerance` resources in DB

#### `AllergyIntolerance` resource examples:

Food allergy

```yaml
resourceType: AllergyIntolerance
id: example
type: allergy
patient:
  reference: Patient/pt-1
category:
- food
criticality: high
recordedDate: '2014-10-09T14:58:00+11:00'
onsetDateTime: '2004'
clinicalStatus:
  coding:
  - system: http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical
    code: active
    display: Active
lastOccurrence: 2012-06
reaction:
- substance:
    coding:
    - system: http://www.nlm.nih.gov/research/umls/rxnorm
      code: '1160593'
      display: cashew nut allergenic extract Injectable Product
  manifestation:
  - coding:
    - system: http://snomed.info/sct
      code: '39579001'
      display: Anaphylactic reaction
  description: Challenge Protocol. Severe reaction to subcutaneous cashew extract. Epinephrine administered
  onset: '2012-06-12'
  severity: severe
code:
  coding:
  - system: http://snomed.info/sct
    code: '227493005'
    display: Cashew nuts
```

No Known Drug Allergy

```yaml
resourceType: AllergyIntolerance
id: nkda
patient:
  reference: Patient/pt-1
recordedDate: '2015-08-06T15:37:31-06:00'
clinicalStatus:
  coding:
  - system: http://terminology.hl7.org/CodeSystem/allergyintolerance-clinical
    code: active
    display: Active
code:
  coding:
  - system: http://snomed.info/sct
    code: '409137002'
    display: No Known Drug Allergy (situation)
  text: NKDA
```

Since there can be several allergies - we should use **Group Table** (or **Group**) for them. It will allow us to grow a form with new elements.

Every table row should have next columns:

* category (text input)
* allergy code (text item)
* reaction (Choice input)
* criticality (Choice input)

> WARN: You should have items with types - that corresponds populate values types. (see [WARN section](how-to-populate-forms-with-data.md#warn))

Reaction and allergy code should be taken from _Terminology_ server, in demo purposes we just set answerOptions with predefined values.

#### Create a table with columns

1. Press `+ Add widget` button in the outline
2. Select `Group Table` in a opened widget panel.

You will get a group table with 2 items in it.

Now we must setup our inputs

1. Remove predefined `Group table's` items
   * hover items with mouse and click on trash icon. (outline)
2. Create `Category` column and set answer options [Category item FHIR Spec](http://hl7.org/fhir/r4/valueset-allergy-intolerance-category.html)
   * Hover `Group Table` item in the outline and click on `+` sign - this will open an items list panel for choosing item.
   * Select `Choice Input` item type in a items list panel
   * Type it's title = `Category` in `text` input of item's settings panel
   * Find `Options` section in `Attributes` segment of `item's settings` panel
   * Fill out options with next value [Category item FHIR Spec](http://hl7.org/fhir/r4/valueset-allergy-intolerance-category.html)
     * `code` = `food` , `display` = `Food`
     * `code` = `medication` , `display` = `Medication`
     * `code` = `environment` , `display` = `Environment`
     * `code` = `biologic` , `display` = `Biologic`
3. Create `Allergy Code` column
   * Repeat actions from 2nd step with next values
   * `text` = `Allergy code`
   * `Options` are
     * `system` = `http://snomed.info/sct`, `code` = `409137002`, `display` = `No Known Drug Allergy (situation)`
     * `system` = `http://snomed.info/sct`, `code` = `227493005`, `display` = `Cashew nuts` (in production we should use ValuseSet here, but for demo purposes we just fill our value from existed `AllergyIntolerance` resource)
4. Create `Reaction` column and set answer options
   * Repeat actions from 2nd step with next values
   * `text` = `Reaction`
   * `Options` are:
     * `code` = `1160593`, `display` = `cashew nut allergenic extract Injectable Product` (in production we should use ValuseSet here, but for demo purposes we just fill our value from existed `AllergyIntolerance` resource)
5. Create `Criticality` column and set answer options
   * Repeat actions from 2nd step with next values
   * Find `Options` section in `Attributes` segment of `item's settings` panel
   * text = `Criticality`
   * `Options` are: [Criticality item FHIR Spec](http://hl7.org/fhir/r4/valueset-allergy-intolerance-criticality.html)
     * `code` = `low` , `display` = `Low Risk`
     * `code` = `high` , `display` = `High Risk`
     * `code` = `unable-to-assess` , `display` = `Unable to Assess Risk`

#### Set table `population expression`

At first we should design and debug a FHIR Query to find `AllergyIntolerance` resources

For searching `AllergyIntolerance` we need only `Patient` reference that we get as `%subject` Input Parameter see Input Parameters section

Complete FHIR Search Query looks like this:

```
GET /AllergyIntolerance?patient=pt-1
```

We should specify form's `named expression` with this query, but with small modifications:

* remove http method (`GET`)
* replace `patient` parameter value (= `pt-1`) with embedded `FHIRPath` expression `{{%subject.id}}`

> ```
> /AllergyIntolerance?patient={{%subject.id}}
> ```

> Embedded FHIRPath expression `{{%subject.id}}` consists of:
>
> * `{{}}` - FHIRPath expression embedding point
> * `%subject` - populate input parameter. (all parameters start with `%` sign)
> * `%subject.id` - `FHIRPath` expression that extracts `id` from `Patient` reference

To specify named expression we should:

1. Click on `group table` item in the outline panel
2. Enable `Populate` section in item's settings panel (`Observation` population should be opened by default)
3. Select `Expression` tab in `Populate` section.
4. enter `expression name` = `allergy` (we will use expression by name in next section)
5. set `expression language` = `FHIRQuery`
6. Copy `FHIRQuery` that we get in last step

#### Set columns `population expressions`

For every column we should set populate expression which extracts data from `%allergy` named expression.

1. Select column item in the outline
2. Enable `Populate` section (`Observation` population should be opened by default)
3. Select `Expression` tab
4. Enter `FHIRPath` expression that extracts needed value.

Category (Choice input)

```fhirpath
%qitem.answerOption.valueCoding.where(code = %allergy.category.first())
```

> There can be several catigories but for demo purpores we just use first of them

Allergy code (Choice item)

```
%allergy.reaction.substance.coding.first()
```

Reaction (Choice input)

```fhirpath
%allergy.reaction.substance.coding.first()
```

> There can be several reactoins but for demo purpores we just use first of them

Criticality (Choice input)

```fhirpath
%qitem.answerOption.valueCoding.where(code = %allergy.criticality)
```

### Populate parameters (usage time)

To pass Patient's reference we use `subject` parameter to `$populatelink`/`$populate` operation.

Operation call example:

```yaml
POST /fhir/Questionnaire/<qid>/$populatelink

resourceType: Parameters
parameter:
- name: subject
  valueReference:
    reference: Patient/example
```

## How to populate form with data from another form during the visit

To populate a form with data from another form we should:

1. setup a form to be able to find another form's response and get information from it (design time)
   * Enable input parameter, that is common for both forms. (`Encounter` in our case)
   * Set form's named expression with `FHIRQuery` to search for response in DB
   * Set item's populate expression to extract data from found `QuestionnaireResponse`
2. provide `Encounter` reference in input parameters of populate operation (usage time)

### Form Setup (design time)

Assume that we have:

* 1st Form and it's response with captured data in DB, which will be used as data source
* 2nd Form, that should be pre-populated

> WARN: You should have items with types - that corresponds populate values types. (see [WARN section](how-to-populate-forms-with-data.md#warn))

> We are working only with 2nd form in this demo

#### Enable input parameter

To use `%encounter` input parameter - we should enable it.

1. Click on form's name in the outline panel (top left corner of the Form Builder)
2. In `Populate section` of form's settings panel click on `Encounter` checkbox.

#### Setup query to find a resource

Response of 1st form should be stored in DB and looks like this:

```yaml
resourceType: QuestionnaireResponse
status: completed
questionnaire: http://aidbox.io/forms/patient-name|1.0.0
encounter:
  reference: Encounter/enc-1
item:
- linkId: patient-name
  text: Patient Name
  answer:
  - valueString: John Smith
```

We are interested in following values from it.

* `encounter reference` - will be common with our form
* `questionnaire` - unique `Questionnaire's` identifier
* item's `linkId` - will be used to extract an answer in following section.

We need to build `FHIR Search Query` to find this response.

It's better to design and debug query in **Aidbox REST Console**

Complete FHIR Search Query looks like this:

```
GET /QuestionnaireResponse?status=completed&questionnaire=http://aidbox.io/forms/patient-name|1.0.0&encounter=enc-1
```

It uses several filter criteria:

* `status = completed` - we need only submitted forms
* `questionnaire` - canonical URL of response's questionnaire
* `encounter` - our common reference, for example `enc-1`

We should specify form's `named expression` with this query, but with small modifications:

* remove http method (`GET`)
* replace `encounter` parameter value (= `enc-1`) with embedded `FHIRPath` expression `{{%encounter.id}}`

> ```
> /QuestionnaireResponse?status=completed&questionnaire=http://aidbox.io/forms/patient-name|1.0.0&encounter={{%encounter.id}}
> ```

> Embedded FHIRPath expression `{{%encounter.id}}` consists of:
>
> * `{{}}` - FHIRPath expression embedding point
> * `%encounter` - populate input parameter. (all parameters start with `%` sign)
> * `%encounter.id` - `FHIRPath` expression that extracts `id` from `Encounter` reference

To specify named expression we should:

1. Click on form's name in the outline panel (top left corner of the Form Builder)
2. In form's settings panel click button `+ Add Expression` (`Named Expressions` section).
3. Select created empty line
4. enter `expression name` = `response` (we will use expression by name in next section)
5. set `expression language` = `FHIRQuery`
6. Copy `FHIRQuery` that we get in last step
7. Click `close` button in the `named expression` form

#### Set item's populate expression

We should use created `named expression` (`%response`) to extract a value and fill out our item.

1. Select the item in outline
2. Enable `Populate` section (`Observation` population should be opened by default)
3. Select `Expression` tab
4. Enter `FHIRPath` expression that extracts needed value.

```fhirpath
%response.repeat(item).where(linkId='patient-name').answer.value
```

### Populate parameters (usage time)

To pass Encounter's reference we use `context` parameter - `encounter` to `$populatelink`/`$populate` operation

Operation call example:

```yaml
POST /fhir/Questionnaire/<qid>/$populatelink

resourceType: Parameters
parameter:
- name: context
  part: 
    - name: name
      valueString: Encounter
    - name: value
      valueReference:
        reference: Encounter/enc-1
```

## How to populate items with Factory API

Populating Choice items can be complicated bacause it needs Coding type answer or it can use ValueSet. FHIRPath expression supports [Factory API](https://build.fhir.org/fhirpath.html#factory) which makes populating more easily.

### 1. Populating a choice item:

Populating patient's gender is tricky because `Patient.gender` is a code while choice item has Coding type. In this case you need to filter out existing options by match code with `Patient.gender`:

```
%qitem.answerOption.valueCoding.where(code=%subject.gender)
```

With factory api it becomes:

```
%factory.Coding(<<system>>, %patient.gender, %patient.gender)
```

Also it supports variables `%patient` or `%subject` . Let's populate patient' gender into Choice item using Factory API.

For this example we will use:

* `%subject` parameter, which will contain `Patient` resource;
* `FHIRPath` expressions to retrieve data;
* `%factory()` expression for construct coding answer.

```
%factory.Coding(%subject.gender.coding.system, %subject.gender.coding.code, %subject.gender.coding.display, %subject.gender.coding.version)
```

Now call `$populate` operation or press `Populate` button with subject patient into debug panel and see QuestionnaireResponse:

```
item:
        - linkId: NuUi_eHv
          text: Gender
          answer:
            - valueCoding:
                system: system
                code: male
                display: Male
                version: '2'
```

### 2. Populating a choice item with answerValueSet

In populate time we don't know codes in ValueSet that is linked to question. So populate these items is impossible. But with Factory API, we could construct coding. For example let's populate patient's marital status into choice item which uses ValueSet [`http://hl7.org/fhir/ValueSet/marital-status`](http://hl7.org/fhir/ValueSet/marital-status)&#x20;

{% code fullWidth="false" %}
```

%factory.Coding(%subject.maritalStatus.coding.system, %subject.maritalStatus.coding.code, %subject.maritalStatus.coding.display, %subject.maritalStatus.coding.version)
```
{% endcode %}

Now call `$populate` operation or press `Populate` button with subject patient into debug panel and see QuestionnaireResponse:

```
linkId: Marital Status
          text: Marital Status
          answer:
            - valueCoding:
                system: http://terminology.hl7.org/CodeSystem/v3-MaritalStatus
                code: D
                display: Divorced
```
