A widget for rendering feature-rich forms defined in JSON definition files

What is LHC-Forms?

LHC-Forms (a.k.a. LForms) is a feature-rich, open-source widget that creates input forms based on definition files for Web-based applications. It was developed by the Lister Hill National Center for Biomedical Communications (LHNCBC), National Library of Medicine (NLM), part of the National Institutes of Health (NIH), with the collaboration and support from the Regenstrief Institute, Inc. and the LOINC Committee.


See the demos for a step-by-step introduction. Features include:


LHC-Forms can be used either as a prebuilt package or installed using npm (npm install lforms), but see the note below about the npm installation). If you aren't using npm, the simplest way to start using LHC-Forms is by linking to the prebuilt version hosted on lhcforms-static.nlm.nih.gov. The URLs for the CSS and JavaScript are:

  1. https://lhcforms-static.nlm.nih.gov/lforms-versions/34.0.0/webcomponent/assets/lib/zone.min.js
  2. https://lhcforms-static.nlm.nih.gov/lforms-versions/34.0.0/webcomponent/lhc-forms.js

The zone.min.js file should be left out if you already have that in your page (e.g. if the page contains an Angular app).

JavaScript for FHIR Support (recommended)
Additionally, you will probably want ONE of the following files for FHIR support. The first file provides support for STU3 and R4 versions of FHIR, and the other two provide support for one specific version.
  • https://lhcforms-static.nlm.nih.gov/lforms-versions/34.0.0/fhir/lformsFHIRAll.min.js
  • OR https://lhcforms-static.nlm.nih.gov/lforms-versions/34.0.0/fhir/R4/lformsFHIR.min.js
  • OR https://lhcforms-static.nlm.nih.gov/lforms-versions/34.0.0/fhir/STU3/lformsFHIR.min.js

Note that the URLs contain a release version number, 34.0.0, for which you can substitute any of the other prebuilt versions (34 or higher) available at https://lhcforms-static.nlm.nih.gov/lforms-versions.

For production applications, if you would prefer to download these files and serve them from your server to avoid introducing a dependency on the lhcforms-static servers, zip files of each version's files are avaialble at https://lhcforms-static.nlm.nih.gov/lforms-versions.

If you decide to use the npm package, note that for now the JavaScript files do not work when the package is required or imported, so you will still need to load the above files from the npm package's directory via script tags. We are hoping to find a solution that will allow them to be imported in the future.


Rendering a Form

In your HTML, create an element to hold the form. You will pass a reference to this element or its ID to a utility function load the form.


<div id="myFormContainer"></div>

Also include the above JavaScript and CSS files on the page.


LForms.Util.addFormToPage(formDefinition, 'myFormContainer', options);
  1. formDefinition - A FHIR Questionnaire, or form definition in LHC-Forms' internal format (either JSON or a parsed object)
  2. formContainer - An element (or its ID, as in this example) into which the form should be placed
  3. options - A map of options. If you are using FHIR and want prepopulation to occur, pass {prepopulate: true}. Note that you probably do not want prepopulation to happen if you are planning to merge in a saved QuestionnaireResponse.

Retrieving User-Entered Data

After the user fills out a form, the data they have entered and things like codes for coded answer lists will be stored in the data model. To retrieve that data, LHC-Forms provides several utility methods. To get the data as a FHIR QuestionnaireResponse (recommended), see the Exporting FHIR part of the FHIR support section. Alternatively, the functions below will return the data in LHC-Forms' internal format.

Getting the form definition combined with the user data

LForms.Util.getFormData(formElement, noEmptyValue, noDisabledItem)

The utility method LForms.Util.getFormData() will return both the user data and the complete form definition data together in a way that can be fed back to LHC-Forms to display the form with the data. This is useful when you want to allow the user to save the form so it can be redisplayed later for completion or editing. The parameters are:

  1. formElement - an HTML element that includes the LForm's rendered form. If this is omitted, the "body" tag will be used. If there is more than one LForm within formElement, the first found will be used.
  2. noEmptyValue - (default false) Remove items that have an empty value
  3. noDisabledItem - (default false) Remove items that are disabled by skip logic

Retrieving only the user-entered values

LForms.Util.getUserData(formElement, noFormDefData, noEmptyValue, noHiddenItem)

To get a compact structure with just the user-entered data and minimal form definition data, you can call LForms.Util.getUserData(formElement, true, true, true). The parameters are:

  1. formElement - an HTML element that includes the LForm's rendered form. If this is omitted, the "body" tag will be used. If there is more than one LForm within formElement, the first found will be used.
  2. noFormDefData - (default false) If this is true, the form definition data will not be returned along with the data, except for item codes. Even when false, the form definition data included is only the item-level data, not the form-level data.
  3. noEmptyValue - (default false) If this is true, items that have an empty value will be removed.
  4. noHiddenItem - (default false) If this is true, items that are hidden by skip logic will be removed.

Retrieving User-Entered Data as HL7 v2 OBR and OBX segments (version >= 12.8)

The user entered data, along with some form definition data can be retrieved as HL7 v2 OBR and OBX segments. To retrieve that data, LHC-Forms provides the following utility method:


The parameter is:

  1. element - (optional if there is only one LHC-Forms widget on the page.) The containing HTML element that includes the LHC-Forms rendered form. It could be the DOM element or its id.

Form Validation

Prior to submitting the form, the form can be checked to make sure required fields are filled in and that the values have the correct format, by using the following function:


An array of errors will be returned if the form is invalid. If the form is valid this function returns null.

The parameter is:

  1. formElement - (optional) an HTML element that includes the LForm's rendered form. If this is omitted, the "body" tag will be used. If there is more than one LForm within formElement, the first found will be used.

Support for FHIR Questionnaire Resources

LHC-Forms can import and export FHIR Questionnaire and QuestionnaireResponse resources. For the current extent of that support, see the documentation for version R4 support" and SDC support. Also, there is partial support for exporting DSTU2 DiagnosticReports, and for importing them if generated by LHC-Forms.

Files for FHIR Support

Because adding support for FHIR (and multiple versions of FHIR) would increase the size of the LHC-Forms library, support for FHIR is added through separate files. See the Installation section for the options for FHIR support files.

Exporting FHIR Resources

The form definition and user-entered data can be retrieved as FHIR resources, using the following utility method:

    LForms.Util.getFormFHIRData(resourceType, fhirVersion, formDataSource, options)

The parameters are:

  1. resourceType - a FHIR resource type. Currently only "DiagnosticReport", "Questionnaire" and "QuestionnaireResponse" are supported as parameter values.
  2. fhirVersion - the version of FHIR being used. This can be set to either "STU3" or "R4".
  3. formDataSource - Optional. Either the containing HTML element that includes the rendered form, a CSS selector for that element, an LFormsData object, or an LHC-Forms form definition (parsed). If not provided, the first LHC-Forms form found in the page will be used.
  4. options - An optional hash of other options, with the following optional keys:
    • bundleType - optional, and only used for DiagnosticReport output. This may be either "transaction" or "collection", and requests that the DiagnosticReport and associated Observation resources be placed together in a bundle of that type. When this is not present, a bundle will not be used.
    • extract - a flag used for resourceType=QuestionnaireResponse to indicate that data should be extracted (using the observationExtract extension). In this case the return value will be an array consisting of the QuestionnaireResponse and any extracted Observations.
    • subject: A local FHIR resource that is the subject of the output resource. If provided, a reference to this resource will be added to the output FHIR resource when applicable.

Importing a FHIR Questionnaire Resource into the LHC-Forms Format

A FHIR Questionnaire resource can be converted/imported into the LHC-Forms format, which can then be loaded into the LHC-Forms widget to show the form. To do that conversion, LHC-Forms provides the following utility method. Note also that the addFormToPage method documented above can take a FHIR Questionnaire, so this step is only needed if you are trying to show a QuestionnaireResponse.

    LForms.Util.convertFHIRQuestionnaireToLForms(fhirData, fhirVersion)

The parameters are:

  1. fhirData - a FHIR Questionnaire resource (parsed). If you run into a problem, please open an issue on the LForms repository.
  2. fhirVersion - the version of FHIR in which the Questionnaire is written (currently takes either "STU3" or "R4"). This maybe be omitted if the Questionnaire resource (in fhirData) contains a meta.profile attribute specifying the FHIR version. If both are provided, this takes precedence.

The return value is a form definition in the LHC-Forms format.

FHIR Context & Queries

If the Questionnaire referenced external FHIR resources or launchContext variables, those will still need to be loaded. Before that can happen, you will need to tell LForms about the connection to the FHIR server, via:

LForms.Util.setFHIRContext(fhirContext, fhirContextVars)

The "fhirContext" parameter should be an instance of 'client-js', a.k.a. the npm package fhirclient, version 2. (See http://docs.smarthealthit.org/client-js for documentation.). A non-npm version, ready to use in a browser, can be found at https://cdn.jsdelivr.net/npm/fhirclient@2/build/fhir-client.min.js. It should be initialized with a connection to the FHIR server to be used. If all that is needed by the Questionnaire are launchContext variables, this parameter can be omitted if the next parameter is provided.

The "fhirContextVars" parameter (optional) is used for the FHIR launchContext which makes variables available to other expressions in a Questionnaire. If provided, fhirContextVars should be a map from launchContext variable names to FHIR resources (as objects). Note that some launchContext variables can be retrieved from the FHIR server (via the fhirContext parameter). Values provided here will take priority over values from fhirContext.

If rendering using LForms.Util.addFormToPage(), the external FHIR resources will be loaded when that is called, and if you have passed in prepopulate=true as an option, prepopulation will also be performed when the resources are loaded. The addFormToPage function returns a promise that will resolve after all external FHIR resources have been loaded (at which point the form should be visible).

Importing a FHIR QuestionnaireResponse into an LHC-Forms Form

FHIR QuestionnaireResponses (and also a DSTU2 version of DiagnosticReports, if generated by LHC-Forms) can be loaded into an LHC-Forms form definition to produce a structure that can be loaded into the LHC-Forms widget (using addFormToPage) To merge FHIR resources into LHC-Forms data, LHC-Forms provides the following utility method:

    LForms.Util.mergeFHIRDataIntoLForms(resourceType, fhirData, formData, fhirVersion)

The parameters are:

  1. resourceType - a FHIR resource type. Currently only "QuestionnaireResponse" and "DiagnosticReport" (either a DiagnosticReport resource with "contained" Observation resources or a "searchset" typed Bundle of a DiagnosticReport and associated Observation resources) are supported.
  2. fhirData - a FHIR resource of the type specified in the resourceType parameter. Note that for DiagnosticReports, the merge will only work if the DiagnosticReport was originally generated by LHC-Forms.
  3. formData - an LHC-Forms form definition or data object. This can be obtained by converting a FHIR Questionnaire.
  4. fhirVersion - the version of FHIR in which the resource is written (currently takes either "STU3" or "R4"). This maybe be omitted if the resource (in fhirData) contains a meta.profile attribute specifying the FHIR version. If both are provided, this takes precedence.

The return value is a form definition object but with the user data merged into it. It can be displayed using LForms.Util.addFormToPage as described above.

Form Definition Format

Form definitions are stored in a JSON structure, which is either FHIR Questionnaire (recommended) or the LHC-Forms internal format. To get a rough idea of what the internal format is you can take a look at one of the samples, or see the form definition documentation.

Licensing and Copyright Notice

See the LICENSE.md file in the lforms package on GitHub.

Issues & Announcements

For reporting problems with LHC-Forms, please open an issue on GitHub. Note that the team developing LHC-Forms also works on several others packages, so we might not be able to respond as quickly as we would like.

To receive occasional announcements about changes or updates to LHC-Forms, sign up for the email list by sending the message "subscribe LHCFORMS-ANNOUNCE" (no subject needed) to listserv@list.nih.gov. These annoucements will probably just be about significant changes.

Project maintained by LHNCBC Hosted on GitHub Pages — Based on theme by mattgraham