-
Notifications
You must be signed in to change notification settings - Fork 30
Skip Logic Relevance View visibility toggle
Skip Logic is defined using the "relevance"
value. This enables a field to be shown only if the condition set in 'ex'
is True
"relevance": {
"step1:Place_Birth": {
"type": "string",
"ex": "equalTo(., \"Health facility\")"
}
}
The field above will only be shown if the value for field whose key is Place_Birth
, which is the Patient's Place of Birth (Location), is equals to "Health Facility"
{
"key": "isDateOfBirthUnknown",
"openmrs_entity_parent": "",
"openmrs_entity": "",
"openmrs_entity_id": "",
"type": "check_box",
"label": "",
"options": [
{
"key": "isDateOfBirthUnknown",
"text": "DOB unknown?",
"value": "false"
}
]
}
"relevance": {
"step1:isDateOfBirthUnknown": {
"type": "string",
"ex": "equalTo(., \"true\")"
}
}
The above is an example showing an example with a checkbox field
The following are the available comparators:
- Equal To -
equalTo
- Greater Than -
greaterThan
- Greater Than or Equal To -
greaterThanEqualTo
- Less Than -
lessThan
- Less Than or Equal To -
lessThanEqualTo
- Not Equal To -
notEqualTo
- Regex Comparison -
regex
The comparators work on the following variable types:
- String -
string
- Numeric
numeric
- Integer, double, float ... - Date
date
- In the formatdd-MM-yyyy
- Array
array
- Arrays are said to be similar if:- Have the same number of items
- Have same items in equal number, irrespective of index
The syntax for the comparison expression ex
:
equalTo(., "Health facility")
is as follows:
comparator($value1, $value2)
$value1
is supposed to be a dot .
so that the value $value1
is that of the referenced field --> Place_Birth
in step1
.
The field reference/identifier uses the field's key
attribute
Check boxes can also be selected multiple times . The corresponding skip logic can also thus become complex. In the example below, (present in the sample app), the CHW Phone Number Widget will only show based on these various conditions:
- Severe Bleeding is checked
- Both Perineal Tear and Placenta Previa are checked
- Both Cord Prolapse and Abnormal Presentation checked or just Prolonged Obstructed Labour is checked
The implementation introduces a new field ex-checkbox
which contains the complex checkbox expression, the example for the above 3 conditions is as below.
The relevant keys of the multi-select checkbox are specified as arrays wrapped with an object key of either and
or or
or both
to be used for simple boolean logic processing.
,
"relevance": {
"step1:delivery_complications": {
"ex-checkbox": [
{
"or": ["severe_bleeding"]
},
{
"and": ["perineal_tear","placenta_previa"]
},
{
"and": [
"cord_prolapse",
"abnormal_presentation"
],
"or": [
"prolonged_obstructed_labour"
]
}
]
}
{
"key": "delivery_complications",
"openmrs_entity_parent": "",
"openmrs_entity": "concept",
"openmrs_entity_id": "161641AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"openmrs_data_type": "select one",
"type": "check_box",
"label": "Any delivery complications?",
"label_text_size": "18sp",
"label_text_color": "#FF9800",
"hint": "Any delivery complications?",
"exclusive": ["none"],
"options": [
{
"key": "none",
"text": "None",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
{
"key": "severe_bleeding",
"text": "Severe bleeding/Hemorrhage",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"text_color": "#000000"
},
{
"key": "placenta_previa",
"text": "Placenta previa",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"text_size": "30sp"
},
{
"key": "cord_prolapse",
"text": "Cord prolapse",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"text_size": "10sp"
},
{
"key": "prolonged_obstructed_labour",
"text": "Prolonged/obstructed labour",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
{
"key": "abnormal_presentation",
"text": "Abnormal presentation",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"text_color": "#FF9800"
},
{
"key": "perineal_tear",
"text": "Perineal tear (2, 3 or 4th degree)",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
},
{
"key": "other",
"text": "Other",
"value": false,
"openmrs_choice_id": "160034AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
}
],
"v_required": {
"value": "false"
}
}
The above relevance example shows a multiple select checkbox example and its used in the sample demo app for the CHW_Phone_Number widget.
If you want to specify relevance on the basis of whether a particular value HAS NOT been checked/selected use the not
key field as shown below. Here, the widget will not show if the severe bleeding
option has been selected
"relevance": {
"step1:delivery_complications": {
"ex-checkbox": [
{
"not": ["severe_bleeding"]
}]
}
OpenSRP Client Native Forms is now integrated with a rules engine for skip logic. We use the J-Easy Library which can be found Here.
Rules are defined in yaml configuration files that are stored in the assets/rule
folder. You can define multiple rules in multiple configs to be used by one json form
When defining the skip logic for your forms keep relevance in separate files. e.g if i am doing a form called physical_exam
, under assets/rules
i should have two files namely
physical-exam-relevance-rules.yml
You can name the files any thing you want so long as you don't mix calculations and relevance definitions.
Separating and naming the files this way per form is however the recommended approach
The j-easy library uses MVEL expression language which is java like to define its rules. There are a few subtle differences but those can be found in the MVEL Documentation Here
Once you have the rules defined, you need to reference them like this in the form's json
{
"key": "happiness_level",
"openmrs_entity_parent": "",
"openmrs_entity": "person_attribute",
"openmrs_entity_id": "relevance_happiness_level",
"type": "edit_text",
"relevance": {
"rules-engine": {
"ex-rules": {
"rules-file": "sample-relevance-rules.yml"
}
}
}
}
In the example above, the relevance for the edit text with key happiness_level
are defined in the assets/rule/sample-relevance-rules.yml
.
The Sample App now has the various sections separated for easier reference. Once you run the app , clicking on the RULES ENGINE LOGIC button guides you through various configurations for relevance and calculations.
You can check out the corresponding rules files under assets/rule
to see how they are configured.
NB:
- When defining rules, always prefix with the step name they reference e.g. if its a key
age
instep 1
then the field reference in the condition should be asstep1_age
e.g.condition: "step1_hepb_immun_status < 60 || step1_hepb_immun_status > 100"
or if field contains a value which is a list like the checkbox widgetstep2_super_heroes.contains('batman')
- The name of the rule should be the key of the field it configures also be prefixed with its step e.g.
name: step1_happiness_level
- The action of a relevance should always be an assignment to the key is relevant e.g.
actions: - "isRelevant = true"
You can also inject global values in the root of the json form and they can be used during the relevance evaluations. useful e.g. if you want to inject external settings that are part of the logic
,
"global": {
"has_cat_scan": true,
"stock_count": 100
},
Here is complete example definition of the relevance for happiness_level
. Its value depends on the first name from step 1 being set to Martin (case sensitive) and a global value for has_cat_scan
being
set to true
.
name: step1_happiness_level
description: Happiness level relevance
priority: 1
condition: "step1_First_Name == 'Martin' && global_has_cat_scan == 'true' "
actions:
- "isRelevant = true"
Forked from Android Native JSON Form Library. Adapted in love by the OpenSRP Community . Apache License, Version 2.0
Introduction
Core Features
Form
Views