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