React Form Engine (RFE) Simplifying UI/UX Development

The React Form Engine (RFE) Form is a game-changing tool for UI/UX developers. The form builder auto-generates form schema JSON files, which can later be loaded into the Form Engine to auto-create micro-frontend user interface forms. This means manual creation of user interface forms can be a thing of the past! Presently, OpenMRS 3.x (O3) react form engine leverages the Carbon design system to get its look and feel to match that of O3.

Extensive documentation of the react form engine can be found here https://ohri-docs.globalhealthapp.net

Core Concepts of the RFE Form Builder

Forms: A form is a collection of form fields classified through pages, sections, and questions, defined by a schema written in JSON.

Pages: A page groups related sections together. Its label identifies it from other pages, so it's important to keep it unique.

Sections: A section groups together related questions and can be rendered either in expanded or collapsed mode.

Subforms: Forms can be broken up into smaller, reusable units within other forms and even programme areas. Subforms also enable mixing encounter types, providing a single user experience.

Component forms: When you have commonly-used form logic, you can structure it as a component form. Components are reusable forms that carry domain-specific information.

Questions: The smallest unit of a form, a question enables a single piece of data to be collected.

image-20240307-110519.png
Example of a form showing Page (In Bold), Sections (TB Program, History of Previous TB Treatment) and Questions.

Field Types

RFE supports almost all the field types from the JSON schema with a few extensions. The most commonly used fields include text, number, select, date, datetime, checkbox, textarea, radio, toggle, content-switcher, fixed-value, group, repeating, file, and ui-select-extended.

Expression Helpers: RFE forms provide a number of expression helper functions that are useful for evaluating complex expressions like isEmpty, today, includes, isDateBefore, and useFieldValue.

Field Validation: RFE Forms is designed to support arbitrarily complex form field validations, broken down into date-based validation and JavaScript expression-based validation.

Rendering Fields Conditionally: You can render Form fields conditionally by defining a hideWhenExpression inside the hide property of your question definitions.

A Deep Dive into Field Types in React Form Engine (RFE)

When building digital forms, the types of fields at your disposal can significantly impact the user experience (UX) and the data you collect. We'll explore the various field types supported in the React Form Engine (RFE).

Text, Number, and Select Fields

The most basic form fields are the text and number inputs, which render as text and number inputs respectively. These allow users to input free text or numerical data. The select field type, on the other hand, renders as a dropdown list, providing users with multiple predefined options to choose from.

Date and DateTime Fields

The date field renders as a date input, revealing a date picker with the current date as the default value when clicked. The datetime field takes it a step further by adding a time picker next to the date input. This field type is ideal for situations where you need users to provide specific dates and times.

Checkbox and Radio Fields

The checkbox field type renders like a multi-choice select field, allowing users to select more than one option. Conversely, the radio field allows users to select only one option from a list of choices.

Textarea Field

The textarea field type renders a textarea input that is 4 rows tall by default. Developers can configure the number of visible text lines by providing a number to the rows property in the questionOptions definition.

Other Field Types

Some of the other field types include the toggle, content-switcher, fixed-value, group, repeating, file, and ui-select-extended.

The toggle field type, suitable for collecting boolean values, renders a toggle input.

image-20240307-111408.png
Toggle

The content-switcher is a custom single-select control from Carbon.

The fixed-value field type can be thought of as a hidden HTML input. It is used when a form needs to persist a predefined non-mutable value on submission.

The group field type is used to create an obsGroup, which links multiple questions together.

The repeating field type renders a repeating group field.

 

 

The file field type renders a file input control that allows users to upload files such as images and PDFs.

Lastly, the ui-select-extended field type is a searchable combo box used to load values from a data source. It works with both inbuilt data sources and custom data sources.

Unleashing the Power of Expression Helpers in RFE Forms

When working with React Form Engine (RFE) forms, a number of expression helper functions are available that make our work smoother and more streamlined.

Commonly Used Expression Helpers

Among the plethora of expression helpers, some are used more frequently due to their general utility in form development. Here's a rundown of these crucial helpers:

  1. isEmpty: This function is instrumental in checking whether a value is null, a blank string, or an empty array.

  2. today: Need the current date? Just call this function and it returns the current date.

  3. includes: If you need to check whether an array of items includes a specific value, this function comes in handy.

  4. isDateBefore: For date comparison needs, this function is your go-to tool.

  5. useFieldValue: This function allows you to return a field value by field ID.

  6. calcBMI: This function takes the height and weight field values and returns the Body Mass Index (BMI) value.

  7. calcEDD: With this function, you can take the last menstruation date value and return the expected date of delivery (EDD).

  8. calcBSA: This function takes the height and weight field values and returns the Body Surface Area (BSA) value.

  9. calcHeightForAgeZscore: This function takes the height and weight and returns the z-score based on the age of the patients for both male and female patients less than 5 years or greater than or equal to 5 years but less than 18 years of age.

  10. calcBMIForAgeZscore: This function takes the patient's height and weight and automatically calculates the BMI and returns the z-score for both male and female patients greater than or equal to 5 years but less than 18 years of age.

  11. calcWeightForHeightZscore: This function takes the patient's height and weight and returns the z-score for both male and female patients less than 5 years.

  12. arrayContains: This function takes in values in an array and returns true if the values are contained in the source array.

  13. arrayContainsAny: This function tests whether the source array contains members (or the values contained in members if it is an array). It returns true if members are in the array, and false otherwise.

  14. calcMonthsOnART: This function takes in the art start date and returns the months the patient has been on art.

  15. calcAgeBasedOnDate: This function takes in the birth date and returns a patient's age.

  16. formatDate: This function takes in a date value, preferred format, and offset value and returns the preferred date format.

  17. calcGravida: This function takes in the parity term and parity aborting numerical values and returns the patient's gravida.

  18. calcTimeDifference: This function takes in a date and returns the difference in days, weeks, months, or years from the current date.

Extending the Form Engine

A user can customize the Form Engine in various ways. For example, you might want to:

  • Add custom expression helpers.

  • Add custom validators and error logic.

  • Add custom components.

  • Add custom fields.

  • Add custom styling.

  • Change how expressions get run.

  • Change how questions, sections and pages get rendered, and so on.

Feature Comparison React Form Engine (RFE) vs Angular Form Engine (AFE).

A great deal of work has gone into making the RFE have parity with the older AFE that has been the default form engine for OpenMRS for a while.

React is often considered more flexible and simpler compared to Angular. It provides developers with more freedom in terms of architecture choices, state management, and tooling but has a relatively steep learning curve, especially for developers who are new to JavaScript frameworks or functional programming concepts. A comparison of the two JS Framework can be found here.

As of March 2024 there is parity between both RFE and AFE. Here is a table comparing both features:

Feature

AFE

RFE

Feature

AFE

RFE

Framework

Angular

React

Core Concepts

 

 

Forms
Pages
Sections
Subforms
Questions
Components

Supported

Supported

Sub-Forms

Not Suppported

Supported

Field Types

 

 

text, number, select, date, datetime, checkbox, textarea, radio, group, repeating, file, and ui-select-extended.

Supported

Supported

toggle, content-switcher, fixed-value

Not Suppported

Supported

Expression Helpers

 

 

isEmpty
today
includes
isDateBefore
useFieldValue
calcBMI
calcEDD
calcBSA
calcHeightForAgeZscore
calcBMIForAgeZscore
calcWeightForHeightZscore
arrayContains
arrayContainsAny
calcMonthsOnART
calcAgeBasedOnDate
formatDate
calcGravida
calcTimeDifference

Supported

Supported

OrderType

Supported

Not yet supported

Workspace Launcher

Supported

Not yet supported

Custom/Undocumented Expression Helpers

 

referenceQuestionAnswers
historicalExpression
HD.getObject
conditionalAnswered
select-concept-answers
shownDateOptions

Supported

Not Supported

I18n

localisable

Not yet supported

Offline

compatible

Not yet supported

Markdown

Not Supported

Supported

Some of the custom extensions found in the Angular Form Engine are referenceQuestionId, referenceQuestionAnswers and some custom implementations of calculateExpression such as Morisky score rating . Documentation of these custom extensions was not sufficiently documented for the team to replicate them.