HtmlFormFlowsheet Module

Introduction

The 'htmlformflowsheet' module is an OpenMRS module that allows you to generically model a paper flowsheet. The basis for the design of this module was originally the WHO Cat-IV treatment card for multi-drug resistant tuberculosis, which contains baseline information (filled out once), and then flowsheet-type information that is appended to the paper form over time (for items such as monthly regimen adherence, monthly smear and culture results, and regimen changes).

htmlformflowsheet custom tag for flowsheets

This module provides basic functionality for embedding small htmlforms inside of larger htmlforms, where the small htmlforms each represent one row in a patient chart. This functionality is provided by the 'htmlformflowsheet' custom htmlform tag (see htmlformflowsheet: custom tag for htmlformentry section).

tabbed interface for flowsheets

Additionally, the module allows you to specify any number of tabs in a tab-based layout, each containing a distinct html form. You can then designate whether or not the html form should be used once (as in baseline demographics), or as a flowsheet (where a new row will be added for every month, as in monthly adherence, for example). Forms that are one-time forms (like baseline demographics and medical history forms) can be as complex as is necessary, and working with these is almost identical to dealing with a stand-alone htmlform externally -- it just all happens within a tab.

Htmlforms that are meant to be flowsheets should represent exactly one row in a table on the paper form. A 'flowsheet' type tab will display the longitudinal history of the entry of this form, and allow you to append new entries, and edit/delete existing entries. 

Any form entry of either type can be viewed and edited later, and this has been optimized for performance such that only that tab will be reloaded after a new entry or edit is made.

(Note: this module was previously called the 'mdrtbpatientchartwidgets' module. The previous 'mdrtbpatientchartwidgets' module will receive no further development. All further development will happen here.)

Status

1.2.2: This version adds the role-based-homepage portlet.  I hope that this will be a fairly short-lived version, because i want to add a configuration data model, and give the option of including portlets in tabs.  I will continue to support this feature, but the setup is going to change.  Here's how it currently works:

Using the "URL-based Interface" syntax describe below, you first need to configure the setting named htmlformflowsheet.programConfigurationMap which maps program Ids to configuration strings.  Here's an example value:

This maps two programs to configurations, programs 5 and 6.

{5:"configuration=S:DEMOGRAPHICS:22:LAST|S:ASTHMA%20INTAKE:38:LAST|F:VISITS:18|F:RENDEZ-VOUS:21|F:MEDICATIONS:26|F:HOSPITALIZATION:17|F:DIAGNOSTICS:20|F:NON%20MEDICAL:23|F:OTHER%20INTERVENTIONS:24|F:SOCIAL%20ASSISTANCE:19&title=ASTHMA%20PROGRAM&showAllEncsWithEncType=true", 6:"configuration=S:DEMOGRAPHICS:33:LAST|S:DIABETES%20INTAKE:37:LAST|F:VISITS:27|F:RENDEZ-VOUS:28|F:INSULIN:31|F:MEDICATIONS:34|F:HOSPITALIZATION:36|F:DIAGNOSTICS:35|F:SOCIAL%20ASSISTANCE:30|F:NON%20MEDICAL:29&title=DIABETES%20PROGRAM&showAllEncsWithEncType=true"}

Next, in your role-based homepage for a given role, you just need to include a new portlet that is included in htmlformflowsheet.  Here's an example role-based homepage:

<!--
       This is a template for what you can put into the role-based homepage module
       to create htmlformflowsheet-based apps.  This is dependent on the global property
       htmlformflowsheet.programConfigurationMap
       which must be set correctly for this to work.
-->

<!-- Set whatever title you want -->
<h3>Non Communicable Disease (NCD) Homepage</h3><br/>

<!--  Here, you must  set two properties.

       First, where you see program=5,6 change these values to all of the programs
       in the global property htmlformflowsheet.programConfigurationMap for which you want this role to be able to
       access the homepage.  You *can't* add properties here that aren't pre-configured in the global property - they
       won't work.

       Second, where you see createPatientFormId=16, change this value to the formId (found under Admin/Manage
       Forms) of the create patient htmlform that you'd like to use for this program.  If you do not wish for this role
       to be able to use the 'create patient' dialogues, you can leave this parameter out, but you will see a benign
       error message instead.
-->

     <openmrs:portlet
          id="htmlformflowsheetFindPatient"
          url="htmlformflowsheetFindPatient"
          parameters="size=full|postURL=|showIncludeVoided=false|viewType=shortEdit|program=5,6|createPatientFormId=16"
          moduleId="htmlformflowsheet"
     />

Notice that the portlet tag includes program Ids 5 and 6, which correspond to the global property described above.  For the create patient widget created by the portlet, you must also specify an htmlform that creates a patient, which in this example is form Id 16.  Here's a sample htmlform for creating a patient that was created by Berchmas, at PIH/IMB Rwanda:

<htmlform>
	<macros>
                headerColor =#009d8e
		fontOnHeaderColor = white
	</macros>

	<style>
		.section {
			border: 1px solid $headerColor;
			padding: 2px;
			text-align: left;
			margin-bottom: 1em;
		}
		.sectionHeader {
			background-color: $headerColor;
			color: $fontOnHeaderColor;
			display: block;
			padding: 2px;
			font-weight: bold;
		}
		table.baseline-aligned td {
			vertical-align: baseline;
		}
               fieldset{
                       /*border: 4px solid #357EC7;*/
              }
div.patientinfo{
 padding:5px 15px 15px 15px;
 border: 4px solid #357EC7;
 -moz-border-radius:2%;
}
	</style>
	<h2>Create Patient (version 0.1)</h2>
<div class="patientinfo">
<br />

<fieldset><legend><b>Name</b></legend>
<patient field="name"/>
</fieldset>
<br />
<fieldset><legend><b>Id Number(s)</b> </legend>
 <patient field="identifier"/>
</fieldset>
<br />

<fieldset><legend><b>Demographics</b></legend>
Gender: <patient field="gender"/> <patient field="birthDateOrAge" />
</fieldset>
<br />
<b>Health Center: </b>
<patient field="identifierLocation" />
<br />
<br />
   <center><submit submitLabel="Save"/></center>
</div>

</htmlform>

1.2: I have recently updated the version of htmlformflowsheet in the module repository to version 1.2.  This version was tested against openmrs1.6.4.x and htmlformentry version 1.7.4.  I have not tested against openmrs1.7 or higher, although i'd be grateful for someone to try this and let me know how it goes.  Additionally, we only use the htmlformflowsheet tag in production, so i have less of an incentive to keep up with the tabbed interface side of the module (although i tested this when adding version 1.2 to the repository).  If someone wants to help me push this functionality forward, that would be a great help.  Version 1.2 also includes full support for the htmlformentry drugOrder tag.  Using htmlformflowsheet  + htmlforms with the drugOrder tag allows you to create a regimen management UI within an htmlform that won't duplicate drug orders.   For a better explanation of how the drugOrder tag, see the HtmlForms Reference wiki page.

TODO:  regimen management screenshot

htmlformflowsheet: custom tag for htmlformentry

The HtmlFormFlowsheet Module now allows you to embed its flowsheet widget into an html form. This means that you can embed multiple htmlforms inside of other htmlforms as flowsheets. Another way to think of this functionality is that the 'flowsheet' view in this module can be embedded in a parent htmlform as a widget.

To do this, all you have to do is upload HtmlFormFlowsheet version 1.1 (or higher), and then in your htmlform xml, you can now use the tag:

<htmlformflowsheet formId="39"/>

In this example, formId corresponds to Form 39, not html_form_id = 39. 'formId' is the only attribute that this tag takes. Here, form #39 will be rendered as a flowsheet in the parent htmlform.  As long as the htmlformflowsheet module is installed on your system, the htmlformflowsheet tag will always be a valid tag within htmlforms.

Example of HTML form with three embedded flowsheets

Screenshot

...
<section headerLabel="1. Allergies">
	<htmlformflowsheet formId="154" />
</section>
<section headerLabel="2. OI">
	<htmlformflowsheet formId="165" />
</section>
<section headerLabel="3. Visit Summary">
	<htmlformflowsheet formId="153" />
</section>
...

By default, the "Add another" button in the flowsheet table will appear at the top of the table, with default text.  You can set the location of this to be the bottom of the table, using the global property value:

htmlformflowsheet.addAnotherButtonPosition:  bottom

You can customize the label for this button within the htmlformflowsheet tag, as described below.

Also by default, the flowsheet table will list encounters in chronological order, most recent at the top, oldest at the bottom.  You can reverse this order by configuring the global property:

htmlformflowsheet.encountersChronology:  asc

Shared Encounter

The HtmlFormFlowsheet Module can now be used to have its htmlformflowsheet widgets either create a new encounter per flowsheet when a new new row is added (available in 1.1), OR, you can choose an existing encounter of the same encounter type to append Obs to. This allows you to use multiple flowsheet widgets to 'build' a month's rendez-vous encounter.

For this to work, all you need to do is add the attribute sharedEncounter="true" to the htmlformflowsheet tag, like this:

<htmlformflowsheet formId="39" sharedEncounter="true"/>

When the sharedEncounter attribute is set to true, users will be prompted to choose from a list of existing encounters.  The Obs will be then appended to the chosen encounter.

The only additional piece of setup that you need for this to work is that you need to make sure that all of the htmlforms that are going to be used in your patient chart to represent a row in an htmlformflowsheet widget are of the *same encounter type*. And, you need htmlformentry module version 1.6.6 or greater.

 

Version 1.1.7

  • you may enter a form uuid instead of the formId number as the argument value for the 'formId' attribute.
  • to change the value of the 'Add New' button, you may use the attribute addAnotherButtonLabel, so for example, this is a valid use of the tag:  <htmlformflowsheet formId="39" sharedEncounter="true" addAnotherButtonLabel="Enter Another Regimen Change" />
  • there's a new global property called htmlformflowsheet.PatientChartFormIds that allows you to put links to patient charts in a patient header  An example value for this global property is 39:2|3|4,43:2,44 .    What this means is that the link to the patient chart with formId 39 should only be visible for patients who have enrolled in programs 2,3,4.  Likewise, the link to the patient chart with formId 43 should only be visible for patient in program 2.  Finally, the link for formId 44 is visible for all patients.
  • if you would like to resize the pop-up window when editing or creating flowsheet rows, you may use the attribute windowHeight.  So, for example, this is a valid use of the tag   <htmlformflowsheet formId="39" sharedEncounter="true" windowHeight="600" />

Version 1.1.9

  • with the attribute showHtmlForm="true", you can instruct the htmlformflowsheet tag renderer to render the specified htmlform in the format described by the htmlform itself, rather than the htmlformflowsheet rendering of the htmlform contents.
  • with the attribute readOnly="true", you can instruct the htmlformflowsheet tag renderer to render the form as usual, but to not give any options to manipulate the rows in the table.

Attributes

  • formID: Form ID of the flowsheet. Note this is NOT the html_form_id.
    • REQUIRED
    • Example: <htmlformflowsheet formId="39" />
    • Value: Form ID integer, or in 1.1.7 and beyond it could be the form's uuid.
    • Default: None
  • addAnotherButtonLabel: Edit the text on the "Add New" button.
    • OPTIONAL/REQUIRED
    • Example: <htmlformflowsheet formId="39" sharedEncounter="true" addAnotherButtonLabel="Enter Another Regimen Change" />
    • Value: String
    • Default: "Add New"
  • readOnly Instruct the htmlformflowsheet tag renderer to render the form as usual, but to not give any options to manipulate the rows in the table.
    • OPTIONAL in module version 1.1.9
    • Example: <htmlformflowsheet formId="39" readOnly="true" />
    • Value: true or false
    • Default: false
  • sharedEncounter: When set to true, Obs entered on the flowsheet will be appended to an existing encounter of the same encounter type.
    • OPTIONAL
    • Example: <htmlformflowsheet formId="39" sharedEncounter="true"/>
    • Value: true or false
    • Default: false
  • showHtmlForm: Instruct the htmlformflowsheet tag renderer to render the specified htmlform in the format described by the htmlform itself, rather than the htmlformflowsheet rendering of the htmlform contents
    • OPTIONAL in module version 1.1.9
    • Example: <htmlformflowsheet formId="39" showHtmlForm="true" />
    • Value: true or false
    • Default: false
  • windowHeight: Adjust the size of the pop-up window.
    • OPTIONAL
    • Example: <htmlformflowsheet formId="39" sharedEncounter="true" windowHeight="600" />
    • Value: Integer
    • Default: ?????
  • conceptsToShow:  Customizes the order of columns (and which columns) to display in the flowsheet table
    • OPTIONAL
    • Example:  <htmlformflowsheet formId="39" conceptsToShow="5090,5089" />
    • Value:  comma-separated string of conceptIds or concept uuids
    • Default:  if this is not supplied, then all concepts from the form are shown on the table in a system-generated order

Tabs:  Building a tabbed interface out of htmlforms

If you only want a single tab-based interface, there are two global properties that allow you to configure your tab layout:

htmlformflowsheet.configuration

This global property essentially does the entire layout of the tabs. Here is an example property value:

   S:Demographics:15:LAST|F:Smear:21|F:Culture:22|F:Labs:20|F:Adherence:23|F:Adverse Effects:17|F:Steering Committee:19|F:Comments:18

These are pipe-delimited entries of the form:

      <<Type>>:<<Title:FormID>>:<<FIRST or LAST>>, where

  • Type can be 'F' for flowsheet, and 'S' for single
  • Title (any text value),
  • Form Id should be the base formID in your database (not the htmlform ID),
  • (optional) the strings 'FIRST' or 'LAST' only apply to Single forms (type 'S'), and determine which form to show, if there are multiple entries of this form for a patient.

htmlformflowsheet.links

This global property allows you to place external links above the rendered tab interface. These are also pipe-delimited and take the form:

   Title:URL

for example, here is a valid sample value: Bacteriologies:/module/mdrtb/mdrtbPatientOverview.form?view=BAC|DSTs:/module/mdrtb/mdrtbPatientOverview.form?view=DST|Regimens:/module/mdrtb/mdrtbPatientOverview.form?view=REG|Treatment Outcomes:/module/mdrtb/mdrtbPatientOverview.form?view=STATUS

Once you have configured these global properties, you can see the results by navigating to:

   module/htmlformflowsheet/patientWidgetChart.list?patientId=33

NOTE: After changing either of these global properties, you will need to stop and start the module in order for your new values to take effect.

URL-driven HtmlForm-based Interfaces

If you would like for your application to have multiple flowsheet layouts, this can be done by adding the URL parameters 'configuration', 'links', and 'fullPage' to the module's URL.

Configuration

This global property essentially does the entire layout of the tabs.

These are pipe-delimited entries of the format:

      <<Type>>:<<Title:FormID>>:<<FIRST or LAST>>, where

  • Type can be 'F' for flowsheet, and 'S' for single
  • Title (any text value),
  • Form Id should be the base formID in your database (not the htmlform ID),
  • (optional) the strings 'FIRST' or 'LAST' only apply to Single forms (type 'S'), and determine which form to show, if there are multiple entries of this form for a patient.

Example

 

https://servername/openmrs/module/htmlformflowsheet/patientWidgetChart.list?patientId=16366&configuration=S:Demographics:207:LAST|F:Prophylaxis:164|F:Allergies:154|F:OI:165|S:Vaccines:179:LAST|F:Visits:153&fullpage=false

This optional parameter allows you to place external links above the rendered tab interface. These are also pipe-delimited and take the form:

   Title:URL

Examples

 

https://concepts.pih-emr.org/openmrs/module/htmlformflowsheet/patientWidgetChart.list?patientId=16366&configuration=S:Demographics:207:LAST|F:Prophylaxis:164&links=DashboardIsHere:/patientDashboard.form?patientId=16366

 

https://concepts.pih-emr.org/openmrs/module/htmlformflowsheet/patientWidgetChart.list?patientId=16366&configuration=S:Demographics:207:LAST|F:Prophylaxis:164&links=Bacteriologies:/module/mdrtb/mdrtbPatientOverview.form?view=BAC|DSTs:/module/mdrtb/mdrtbPatientOverview.form?view=DST|Regimens:/module/mdrtb/mdrtbPatientOverview.form?view=REG|Treatment%20Outcomes:/module/mdrtb/mdrtbPatientOverview.form?view=STATUS

 

fullPage

This optional parameter allows you to specify whether or not you want to include the OpenMRS header and footer. The only two allowed values are "true" and "false". If you specify fullPage=true, you get the default 'everything' view of the configured tabs. Or when omitted from the URL the full page including header and footer are displayed. If you specify fullPage=false, you don't get the header, patient header, or footer, making the tabs suitable for insertion into a ui framework (tested against the ui.springmvc module).  Note, fullPage is case sensitive in respect to both the parameter name and parameter value.

 

 

 

fullPage=true or fullPage parameter is omitted

Header and Footer are displayed

fullPage=false

Header and footer are hidden

title

Htmlformflowsheeet version 1.2.1 additionally adds the parameter 'title' which puts the title argument above the flowsheet tabs.  For example you could add &title=ASTHMA%20PROGRAM to add ASTHMA PROGRAM to the top of the tabbed interface.  Other parameters that work across all tabs are 'showHtmlForm', which will change the flowsheet renderer to use htmlformentry native rendering if set to true rather than htmlformflowsheet default rendering, and 'showAllEncsWithEncType', which will allow you to append the data entered in a flowsheet to already existing encounters.

For example, if you navigate to the following, you get the default tab view for patient #33.

      module/htmlformflowsheet/patientWidgetChart.list?patientId=33

If you navigate to the following, you get a tab view with only the culture and lab forms, and a link to mdrtb treatment outcomes.

      module/htmlformflowsheet/patientWidgetChart.list?patientId=33&configuration=F:Culture:22|F:Labs:20&links=Treatment Outcomes:/module/mdrtb/mdrtbPatientOverview.form?view=STATUS

Note:  on single htmlforms, when displayed, i would recommend getting rid of the default 'print' and 'delete' links that render by default in htmlformentry.  To do this, add the following javascript to your htmlform:

<script>
   $j(document).ready(function() {
      $j('#htmlFormEntryBanner').remove();
 });
</script>

Examples

Here is one-time form in the tab structure:  http://archive.openmrs.org/wiki/Image:Single.JPG

This is a flowsheet-type form in the tab structure:   http://archive.openmrs.org/wiki/Image:Flowsheet.JPG

keywords:  flowsheet, patient chart, htmlformentry, formflowsheet, treatment card, tabs

 

Unreleased Version (1.3.0 Snapshot) with working tabbed Interface

The most updated HTML Form Flowsheet module version with working tabbed interface is the Github 21 Febrary 2013 master branch snapshot.

This has been tested with:

  • OpenMRS 1.8.4
  • HTML Form Entry 1.10.0