React-based autogenerated DHIS2 custom forms using a single custom form. This tool is part of EyeSeeTea's DHIS2 Suite designed to ease the integration of data from excel into DHIS2 and generate templates for datasets and programs.
$ nvm use # Install node from .nvmrc
$ yarn install
Start the development server at http://localhost:8082 using https://play.dhis2.org/2.34 as a backend:
$ PORT=8082 REACT_APP_DHIS2_BASE_URL="https://play.dhis2.org/2.34" yarn start
Expected structure of the metadata:
- Maintenance -> Data set -> Edit: Add all the data elements that need to be displayed.
- Maintenance -> Data set -> Manage sections: Create a section for each table to display in the form.
Data sets, sections and data elements are customizable using the data store:
http://localhost:8080/dhis-web-datastore/index.html#/edit/d2-reports/autogenerated-forms
An example:
{
"dataElements": {
"DE_CODE1": {
"selection": {
"isMultiple": true,
"optionSet": {
"code": "OPTION1_CODE"
}
}
}
},
"dataSets": {
"DS1_CODE": {
"viewType": "table",
"texts": {
"header": "<h2>Header from dataStore</h2>",
"footer": "<h3>Footer from dataStore</h3>"
}
},
"DS2_CODE": {
"viewType": "grid",
"sections": {
"SECTION1_CODE": {
"viewType": "table",
"texts": {
"header": "<h2>Section header from dataStore</h2>",
"footer": "<h3>Section footer from dataStore</h3>"
}
}
}
},
"DS3_CODE": {
"sections": {
"SECTION2_CODE": {
"viewType": "grid-with-periods",
"toggle": {
"type": "dataElement",
"code": "CODE_OF_DATA_ELEMENT"
},
"periods": {
"type": "relative-interval",
"endOffset": 0,
"startOffset": -2
}
}
}
}
}
}Section contents can be optionally shown/hidden using a dataElement as toggle. In the section configuration:
{
"toggle": {
"type": "dataElement",
"code": "CODE_OF_DATA_ELEMENT"
}
}Data elements will be shown in the first column and the value in the second.
An example, a section with data elements:
- `ITNs - Policy`
- `ITNs - Implemented`
This will create this table:
| |
ITNs - Policy | |
ITNs - Implemented | |
Data elements will by grouped by rows and columns using formName/name and " - " as a separator of subsection / data element.
An example, a section with data elements:
- `ITNs - Basic - Written Policy`
- `ITNs - Basic - Policy Implemented`
- `ITNs - Extended - Written Policy`
- `ITNs - Extended - Policy Implemented`
This will create this table:
| Written Policy | Policy Implemented |
ITNs - Basic | | |
ITNs - Extended | | |
NOTE: The section processor detects if all the data elements are indexed, and in that case a special. An example:
Data elements:
- `MAL - Compound name (1)`
- `MAL - Compound name (2)`
- `MAL - Compound symbol (1)`
- `MAL - Compound symbol (2)`
Output:
# | Compound name | Compound symbol
1 | |
2 | |
Data elements will by grouped by rows and subrows using formName/name and " - " as a separator of subsections.
An example, a section with data elements:
- `ITNs - Basic`
- `ITNs - Extended - Written Policy`
- `ITNs - Extended - Policy Implemented`
- `ITNs - Extended - Policy Extra`
And having a configuration in the dataStore:
{
"SECTION_CODE": {
"viewType": "grid-with-periods",
"periods": {
"type": "relative-interval",
"endOffset": 0,
"startOffset": -2
}
}
}And rendering a data entry for 2022, will create this table for interval [2022-2 .. 2022+0]:
| 2020 | 2021 | 2022 |
--------------------------------------------------------------------
ITNs - Basic | | | |
| Written Policy | | | |
ITNs - Extended | Policy Implemented | | | |
| Policy Extra | | | |
Data elements will by grouped by rows and columns using data element formName/category option combo names and " - " as a separator of subsections.
An example, a section with data elements and associated category option combos:
Data element Category option combos
- ITNs - Basic [Public, Private, Community, Combined]
- ITNs - Extended - Written Policy [Public, Private, Community, Combined]
- ITNs - Extended - Policy Implemented [Public, Private, Community, Combined]
- ITNs - Extended - Policy Extra [Public, Private, Community, Combined, default]
This will create this table:
| Public | Private | Combined | Community | default
----------------------------------------------------------------------------------------------------
ITNs - Basic | | | | |
| Written Policy | | | | |
ITNs - Extended | Policy Implemented | | | | |
| Policy Extra | | | | |
Data elements are grouped by their disaggregated category option combos.
It allows for a more structured view of data elements and their category option combinations, making it easier to analyze and visualize the data.
An example section with data elements:
Data element Categories Category option combos
ITNs - By age group and gender Age group => [0-12, 12-18, 18-24, 25-49, 50+] "0-12, Male", "0-12, Female", "12-18, Male", "12-18, Female", "18-24, Male", "18-24, Female", "25-49, Male", "25-49, Female", "50+, Male", "50+, Female"
Gender => [Male, Female]
ITNs - By age group and gender (Policy Extra) Age group => [0-12, 12-18, 18-24, 25-49, 50+] "0-12, Male", "0-12, Female", "12-18, Male", "12-18, Female", "18-24, Male", "18-24, Female", "25-49, Male", "25-49, Female", "50+, Male", "50+, Female"
Gender => [Male, Female]
The grouping is done by separating the category option combination names with a separator (", "). This will create this table:
| ITNs - By age group and gender | ITNs - By age group and gender (Policy Extra)
---------------------------------------------------------------------------------------------------------------------------
| 0-12 | 12-18 | 18-24 | 25-49 | 50+ | 0-12 | 12-18 | 18-24 | 25-49 | 50+ |
---------------------------------------------------------------------------------------------------------------------------|
Female | | | | | | | | | | |
Male | | | | | | | | | | |
Each dataset entry in "dataSets" can optionally contain rules.
Only one action type is supported at a time (i.e. if there are two rules with displayWarning action, only the first will execute).
{
"rules": [
{
"conditions": {
"periodIn": ["2025", "2024"]
},
"action": {
"type": "displayWarning",
"text": { "code": "CONSTANT_CODE" },
"blockEntry": true
}
}
]
}
Conditions supported:
periodIn: array of periods
Actions supported:
displayWarning:textcan be a literal string or a constant referenceblockEntryif true it will open a modal that cannot be dismissed
On development, you need to specify the orgUnit/dataSet/period manually on the URL:
http://localhost:8081?orgUnit=ID&dataSet=ID&period=PERIOD
Setting the environment variable REACT_APP_DEBUG=true enables debug mode.
This will print section and dataElement codes to the screen. This makes easier the analysis of autogenerated forms and having codes accessible for dataStore configuration.
First create the data entry form:
$ yarn build-autogenerated-forms
This creates dist/custom-data-form.html, which can be directly pasted as a DHIS2 data.
Set custom form (Maintenance -> Data set -> Right-click on data set -> Design
data entry form -> {Source code} -> Paste HTML -> {Save}) or posted using the API to dataSet.dataEntryForm.htmlCode.
# Deploy to an specific dataset:
$ yarn deploy dataSetId # use --force to deploy even if the dataset is not currently using d2-autogen-forms
# Deploy to all datasets using d2-autogen-forms:
$ yarn deploy
# View help / more options:
$ yarn deploy -hThe configurator app allows to edit the JSON config for autogen-forms for each DataSet. It provides validations for the configuration object.
Create the autogenerated configurator app:
$ REACT_APP_REPORT_VARIANT=autogenerated-forms-configurator yarn start # start dev server
$ yarn build-configurator # Creates d2-autogen-configurator.zip