Patient Fragments, Best Practices and Style Guide

The UI Framework code is being transitioned to a module. Documentation will move to UI Framework.

Summary

When writing a fragment that goes on patient pages, you should follow all these best practices, so that the fragment works consistently with all the others.

Level 1 - For all fragments
  • Use the utility method to get the Patient from the PageModel or FragmentConfiguration
  • If the data you are going to display is easily available, then draw it all on page load without AJAX
    • Doing AJAX calls on page load is a performance-killer over high-latency satellite connections.
    • You should use AJAX for intensive calculations that would significantly slow down the initial page draw
  • Don't decorate yourself. Allow the consumer that is calling you to choose your decoration.
  • Wrap a div with an id around the entire visible area of your fragment
    • allow the consumer to set that id (in groovy: def id = config.id ?: ui.randomId("prefix")
Level 2 - Fragments that can refresh via AJAX
  • Remember that even if your fragment is capable of refreshing itself via AJAX, it must draw itself without any AJAX calls on page load.
  • Your fragment should refresh itself (fetch data from the server, and redraw) on the "YOUR-FRAGMENT-ID.refresh" message
  • If you modify any patient data, you should publish a message like "patient/patientId/relationships.changed". (See below for messages we've defined so far.) This message must contain a standard javascript object representing the patient as its payload.
    • Ideally you can return this object as the JSON response from your fragment action on success.
    • Alternately you may call the patientChanged(patientId, property) function (from openmrs.js), which will fetch the patient from the server and then publish "patient/patientId/category.changed". (This is easier, but requires an extra server round-trip.)
  • Your fragment should also refresh itself on any of these messages: (see below for the payloads of these messages)
    • person/personId.changed
    • patient/patientId.changed
    • person/personId/yourproperty.changed (if 'yourproperty' is on Person as opposed to Patient)
    • patient/patientId/yourproperty.changed (if 'yourproperty' is on Patient)

Details

controller() method

Patient fragments should typically work on the patient from the shared PageModel, but the consumer should be able to override that by providing a patient or patientId in the FragmentConfiguration. You should start your controller fragment by calling the utility method FragmentUtil.getPatient(PageModel, FragmentConfiguration).

Standard messages

Message

Meaning

Promised Content

person/personId.changed

One or many unspecified properties of the person have changed

Standard javascript person object with TBD properties

patient/patientId.changed

One or many unspecified properties of the patient have changed

Standard javascript patient object with TBD properties

person/personId/names.changed

Names have been added, edited, removed, or preferred

personId, names[] (with uuid, givenName, middleName, familyName, familyName2, preferred)

person/patientId/addresses.changed

Addresses have been added, edited, removed, or preferred

personId, addresses[] (with uuid, address1, address2, ..., preferred)

patient/patientId/identifiers.changed

Identifiers have been added, edited, removed, or preferred 

patientId, activeIdentifiers[] (with id, identifierType*, identifier, location*, preferred)

* = OpenmrsMetadata will be typically returned as an object with id and label properties