Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

A form is a collection of fields classified through pages, sections and questions. These fields are rendered differently based on their associated question type and rendering. For example, a text field dropdown will behave differently than from a dropdown.

Forms are described using JSON schemas that conform to the O3 standard JSON schema spec. This standard JSON schema ensures that schemas built using either the Angular or React form engines have parity. Below is an example of a form rendered using the Form Engine:

...

Element

Type

Description

name

string

The name of the form. This is required and should be unique within the system.

uuid

string

The unique form identifier

encounterType

string

The encounter type uuid associated with the form’s encounter. This defines the context in which the form is used.

inlineRendering

single-line / multi-line / automatic

The inline rendering mode

pages

Array<Section>

A collection of pages that make the form. Each page contains sections and questions.

availableIntents

Array<Intent>

A list of intents supported by this form. Intents define specific actions associated with the form.

Pages

A page is a collection of related sections. A typical page definition consists of a label, inlineRendering (optional) and a list of sections. The engine uses the page’s label to identify it from other pages; that being said, it’s mandatory to keep the page’s label unique. Below is an example of a form with one page and section. The section has 4 questions labelled:

...

Additional form properties

Validators

array of objects

These are the conditions that validate the input data.

Default

string/ number/boolean,/object

Default values for fields in the form.

Required

boolean

Fields that must be filled out or selected.

historicalExpression

string

Expression or data related to historical information.

Hide

object

The option to hide certain parts of the form or fields.

CalculatedExpressions

string

Expressions that calculate values based on inputs.

questionInfo

string

These are additional information or context about a question.

answers

array of objects

Responses or answers provided in the form.

orderType

string

Type of order or sequence for form elements.

selectableOrders

array of objects

Orders that can be selected or applied.

conceptMappings

array of objects

This is the mapping of concepts to specific form elements.

Concept ID

string

Identifier for a specific concept within the form.

Pages

A page is a collection of related sections. A typical page definition consists of a label, inlineRendering (optional) and a list of sections. The engine uses the page’s label to identify it from other pages; that being said, it’s mandatory to keep the page’s label unique. Below is an example of a form with one page and section. The section has 4 questions labelled:

Code Block
languagejson
{
  "name": "HTS Retrospective Form",
  "pages": [
    {
      "label": "Eligibility Screening",
      "sections": [
        {
          "label": "Testing history",
          "isExpanded": "true",
          "questions": [
            {
              "label": "What is the reason for conducting the HIV test?",
              "type": "obs",
              "questionOptions": {
                "rendering": "select",
                "concept": "ce3816e7-082d-496b-890b-a2b169922c22",
                "answers": [
                  {
                    "concept": "7398c91a-8db8-480d-8130-1a92cc208ded",
                    "label": "Inconclusive HIV Result",
                    "conceptMappings": []
                  },
                  {
                    "concept": "a6ad599d-2bc4-47b7-81fe-a38e88867c1d",
                    "label": "Self Initiative",
                    "conceptMappings": []
                  },
                  {
                    "concept": "0e65e5fd-a1d8-4730-a991-75a1d703cba6",
                    "label": "HIV Self Test Positive",
                    "conceptMappings": []
                  },
                  {
                    "concept": "6e768c50-a239-45ff-9920-2c6a9352320e",
                    "label": "Index Client Testing",
                    "conceptMappings": []
                  },
                  {
                    "concept": "cb099534-b609-4561-9d4c-dd2fc74cedaf",
                    "label": "Assisted Partner Notification (APN)",
                    "conceptMappings": []
                  },
                  {
                    "concept": "5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    "label": "Other"
                  }
                ]
              },
              "id": "reasonForTesting"
            },
            {
              "label": "Has the client ever been tested for HIV?",
              "type": "obs",
              "questionOptions": {
                "rendering": "radio",
                "concept": "1492AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                "answers": [
                  {
                    "label": "Yes",
                    "concept": "cf82933b-3f3f-45e7-a5ab-5d31aaee3da3"
                  },
                  {
                    "label": "No",
                    "concept": "488b58ff-64f5-4f8a-8979-fa79940b1594"
                  },
                  {
                    "concept": "1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    "label": "Unknown"
                  }
                ]
              },
              "id": "everTestedForHIV"
            },
            {
              "label": "How recently has the client been tested for HIV within any of the following periods?",
              "type": "obs",
              "questionOptions": {
                "rendering": "select",
                "concept": "e7947a45-acff-49e1-ba1c-33e43a710e0d",
                "answers": [
                  {
                    "concept": "909edba5-c9b1-44e3-92ee-f95269964fe1",
                    "label": "0-3 Months",
                    "conceptMappings": []
                  },
                  {
                    "concept": "8df190d5-7a65-4b53-9b4a-b35b9cf400b1",
                    "label": "3-6 Months",
                    "conceptMappings": []
                  },
                  {
                    "concept": "c85e6df3-7184-400e-a686-f41aaae08113",
                    "label": "6-12 Months",
                    "conceptMappings": []
                  },
                  {
                    "concept": "8de5bf3f-8058-4735-ae50-b5a986b2362b",
                    "label": "More Than 12 Months",
                    "conceptMappings": []
                  },
                  {
                    "concept": "1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    "label": "Unknown"
                  }
                ]
              },
              "id": "durationSinceLastHIVTest"
            },
            {
              "label": "What was the result of the last HIV test?",
              "type": "obs",
              "questionOptions": {
                "rendering": "select",
                "concept": "159427AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                "answers": [
                  {
                    "concept": "6378487b-584d-4422-a6a6-56c8830873ff",
                    "label": "Positive",
                    "conceptMappings": []
                  },
                  {
                    "concept": "664AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    "label": "Negative"
                  },
                  {
                    "concept": "7398c91a-8db8-480d-8130-1a92cc208ded",
                    "label": "Inconclusive",
                    "conceptMappings": []
                  },
                  {
                    "concept": "1067AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
                    "label": "Unknown"
                  }
                ]
              },
              "id": "lastHIVTestResult"
            }
          ]
        }
      ]
    }
  ],
  "uuid": "xxxx",
  "encounterType": "79c1f50f-f77d-42e2-ad2a-d29304dde2fe"
}

...

  • label: The actual content of the question. This label is what gets rendered as the question label. If no label is specified, the "display" value of the concept is used (which is generally the preferred name for the concept in the current locale)

  • type: Provides information of how the submission value will be processed. It helps the engine map the target submission handler to a field. Currently supported types include: obs | obsGroup | encounterLocation

    • obs: questions of this type will yield an observation as a submit-able.

    • obsGroup: questions of this type will yield an obs group as a submit-able.

    • encounterLocation: questions of this type will capture a location that will be associated to the current encounter.

  • questionOptions: An object defining other properties of a question:

    • rendering: The field type of the question. Currently supported types include: select | text | date | number | checkbox | radio | repeating | group | content-switcher | encounter-location | textarea | toggle | fixed-value read more about supported types.

    • concept: The concept UUID or concept reference mapping in the format "source:term" (for example "CIEL:1234") of the backing concept for this field.

    • defaultValue: The default value to be associated to this question.

    • answers: An array of answers scoped to a question. An answer definition consists of a concept UUID or mapping and label pair. If no label is specified, the "display" value of the concept is used. Below is an example of answers to a Current HIV status question:

  • questionInfo: A property that recieves a string containing additional information regarding the field. When hovered over, it displays a tooltip containing the information passed.

    Code Block
    languagejson
    {
      "questionInfo": "sample tooltip info for text"
    }

image-20240418-155410.pngImage Removed

  • isHidden: A boolean value that determines field visibility. In most cases, this value is driven by hide expressions.

  • hide: You can use this to define logic for hiding a question based on certain conditions. To do so, you provide a JavaScript expression that evaluates to a boolean value:

    Code Block
    languagejson
    {
      "hide": {
        "hideWhenExpression": "onArt!== 'a899b35c-1350-11df-a1f1-0026b9348838'"
      }
      // This logic hides the question with the `onArt` id if the value of its
      // concept does not match the supplied value
    }
  • required: If set true, that form field is considered to be mandatory. Defaults to false.

  • unspecified: If set true, the form engine will render a widget(as part of this field) that can be used to mark this field as unspecified. By default, a mandatory field can't pass validation without a valid value. However, think of a scenario where it’s almost impossible to provide a value eg. when filling out a form in retrospective where a value wasn’t collected on the paper form. For such scenarios, a required field can be marked as unspecified.

Note

What is the value of Unspecified?

Unspecified does not create an observation in the database. It is the equivalent of a NULL value in database systems (but does not create a NULL value). Unspecified is not a concept. It is rendered by the form engine and not persisted in the database.

  • validators: An array in which you provide validation logic for the specific question. Learn more about validators.

  • behaviours: An array of supported behaviours. Learn more about form behaviours.locale)

  • type: Provides information of how the submission value will be processed. It helps the engine map the target submission handler to a field. Currently supported types include: obs | obsGroup | encounterLocation

    • obs: questions of this type will yield an observation as a submit-able.

    • obsGroup: questions of this type will yield an obs group as a submit-able.

    • encounterLocation: questions of this type will capture a location that will be associated to the current encounter.

  • questionOptions: An object defining other properties of a question:

    • rendering: The field type of the question. Currently supported types include: select | text | date | number | checkbox | radio | repeating | group | content-switcher | encounter-location | textarea | toggle | fixed-value read more about supported types.

    • concept: The concept UUID or concept reference mapping in the format "source:term" (for example "CIEL:1234") of the backing concept for this field.

    • defaultValue: The default value to be associated to this question.

    • answers: An array of answers scoped to a question. An answer definition consists of a concept UUID or mapping and label pair. If no label is specified, the "display" value of the concept is used. Below is an example of answers to a Current HIV status question:

  • questionInfo: A property that recieves a string containing additional information regarding the field. When hovered over, it displays a tooltip containing the information passed.

    Code Block
    languagejson
    {
      "questionInfo": "sample tooltip info for text"
    }

image-20240418-155410.pngImage Added

  • isHidden: A boolean value that determines field visibility. In most cases, this value is driven by hide expressions.

  • hide: You can use this to define logic for hiding a question based on certain conditions. To do so, you provide a JavaScript expression that evaluates to a boolean value:

    Code Block
    languagejson
    {
      "hide": {
        "hideWhenExpression": "onArt!== 'a899b35c-1350-11df-a1f1-0026b9348838'"
      }
      // This logic hides the question with the `onArt` id if the value of its
      // concept does not match the supplied value
    }
  • required: If set true, that form field is considered to be mandatory. Defaults to false.

  • unspecified: If set true, the form engine will render a widget(as part of this field) that can be used to mark this field as unspecified. By default, a mandatory field can't pass validation without a valid value. However, think of a scenario where it’s almost impossible to provide a value eg. when filling out a form in retrospective where a value wasn’t collected on the paper form. For such scenarios, a required field can be marked as unspecified.

Note

What is the value of Unspecified?

Unspecified does not create an observation in the database. It is the equivalent of a NULL value in database systems (but does not create a NULL value). Unspecified is not a concept. It is rendered by the form engine and not persisted in the database.

  • validators: An array in which you provide validation logic for the specific question. Learn more about validators.

  • behaviours: An array of supported behaviours. Learn more about form behaviours.

  • isTransient The RFE supports the ability to make a form field transient. Making a field transient means that the data entered into the form is not saved permanently. This functionality can be easily integrated into the JSON format, as demonstrated below.

Code Block
        "questionOptions": {
          "isTransient": "true",
          "rendering": "date",
          "concept": "160555AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
        },

Components

...

There may be situations where you might want to separate commonly-used form logic into separate reusable bits. In such cases, you can structure that logic as a component form. Components can therefore be thought of as reusable forms that carry domain-specific information. Imagine a situation where you're creating many forms for use in a Point of Care setting. You might find that multiple forms might need to have sections for collecting pre-clinic Review information. This pre-clinic Review information could include details such as:

...