Dynamic Forms

Concepts overview for R&D

configuration

  • view-model
  • layout

clinical

  • model
  • meta-data

Evn

lookups

i18n

user data

etc.

Save

Cancel

Model - Meta-Data

Model :

  • the clinical entities (e.g. patient, visit, order)
  • raw data
  • functionality (e.g. calcFullName(),  isOrderUrgent())
  • schema dependent by configuration
  • redux inspired single source of truth

Meta-Data -

  • auto-generated
  • description of the structure of the Model
  • includes raw data and functionality (TBD)
  • dynamic-form related extended info (defaults)
  • schema-dependent

model - metadata

// model

{
    personKey: 1030210250.0,
    lastName: "Davidson",
    firstName: "David",
    get fullName() { return
        `${this.lastName}, ${this.firstName}`;
    },
    visit: [
        {
            visitKey: 2000009164.0,
            patientClass: "Emergency",
            orders: [
                {
                    orderKey: 1203000316539.0,
                    reasonForOrder: "test me"
                }
            ]
        }
    ]
}
// metadata

{
    personKey: { type: 'number', id: true },
    lastName: { type: 'text' },
    firstName: { type: 'text' },
    fullName: { type: 'text', calculated: true },
    visit: {
        type: 'group',
        multiple: true,
        fields: {
            visitKey: { type: 'number', id: true },
            patientClass: { type: 'text' },
            orders: {
                type: 'group',
                multiple: true,
                fields:  {
                    orderKey: { 
                        type: 'number',
                        id: true
                    },
                    reasonForOrder: { type: 'text' }
                }
            }
        }
    }
}

view-model

 

  • describes the form's functionality
  • binding (linking data and ui)
  • behavior (inter-fields relations, show hide, validations e.g.)
  • does not define view properties
// view-model

{
    lable: 'Patient Form',
    fields: {
        firstNameField: {
            lable: 'First Name',
            path: 'firstName'
        },
        lastNameField: {
            lable: 'Last Name',
            path: 'lastName'
        },
        fullNameField: {
            lable: 'Full Name',
            path: 'fullName'
        },
        orderKeyField: {
            lable: 'Order Key',
            path: 'visit.0.orders.0.orderKey'
        }
    }
}

layout

The layout adds visual description to the

view model:

  • Orientation: Vertical/Horizontal
  • Navigation: Tabs etc. 
  • Collapsible boxes
  • Pop Up (activated by buttons)
  • Styling properties such as colors
  • Has the same structure as the view model

 

// layout

{
    align: Alignment.Tabs, 
    // optional- Alignment.Vertical,
    //           Alignment.Horizontal
    children: [
        {
            fieldName:
                'firstNameField'
        },
        {
            fieldName:
                'lastNameField'
        },
        {
            fieldName:
                'fullNameField'
        },
        {
            fieldName:
                'orderKeyField'
        }
    ]
}

Collapsible boxes

Popup

Tabs

Validations

  • field level
  • defined in the view model
  • visual indication bubble up to the relevant level
  • validation for example:
    • is number
    • required
// view-model

{
    lastNameField: {
        lable: 'Last name',
        path: 'lastName',
        validations: {
            required: true
        },
        validationsErrorMessage: 
            "Last name is required"
    },
    ...
}

lookups

// model

{
    ...
    genderKey: 2.0,
    FKLookupRows: {
        genderKey: {
            genderKey: 2.0,
            description: "Male"
        }
    }
}
// metadata

{
    ...
    genderKey: {
        type: 'lookup',
        lookupName: 'GENDER',
        lookupKey: 'genderKey',
        lookupDescription: 'description'
    }
}
// view-model

{
    gender: {
        lable: 'Gender',
        path: 'genderKey'
    },
    ...
}
  • supports two user interfaces
  • run-time mechanism auto optimization

Form & Sub-Forms

 

View Model - Modularity

 View Model is structured using:

  • model properties (e.g. firstName)
  • calculated properties (e.g. isOrderCritical())
  • Sub View Models
    • Pregnancy Details View Model
    • may be applied to their relevant input
  • Custom components
    • Pre-developed components to handle complex structures and behavior 
{
    "label": "My Form",
    "fields": {
        "group_1": {
            "label": "Pregnancy",
            "fields": {
                "field_1": {
                    "label": "Breast feeding",
                    "path": "visit.0.orders.0.cbIsBreastfeeding"
                },
                "field_2": {
                    "label": "Pregnancy",
                    "path": "visit.0.orders.0.cbOPregnant"
                }
            }
        },
        "group_2": {
            "label": "Clinical Indications",
            "fields": {
                "field_1": {
                    "label": "Diabetic",
                    "path": "visit.0.orders.0.siteProtCOClinicalInd.0.cbIsSpoDiabetic"
                },
                "field_2": {
                    "label": "Asthmatic",
                    "path": "visit.0.orders.0.siteProtCOClinicalInd.0.cbIsSpoAsthmatic"
                }
            }
        }
    }
}

Form & Sub-Forms

server side

// id: 235
{
    "label": "My Form",
    "fields": {
        "group_1": {
            "storedFormId": 422
        },
        "group_2": {
            "storedFormId": 423
        }
    }
}
// id: 422
{
    "label": "Pregnancy",
    "fields": {
        "field_1": {
            "label": "Breast feeding",
            "path": "visit.0.orders.0.cbIsBreastfeeding"
        },
        "field_2": {
            "label": "Pregnancy",
            "path": "visit.0.orders.0.cbOPregnant"
        }
    }
}
// id: 423
{
    "label": "Clinical Indications",
    "fields": {
        "field_1": {
            "label": "Diabetic",
            "path": "visit.0.orders.0.siteProt..."
        },
        "field_2": {
            "label": "Asthmatic",
            "path": "visit.0.orders.0.siteProt..."
        }
    }
}
form sub-form
235 422
235 423

when the client asks for form #235, the server will return the form + all of its descendants sub-forms

Forms & Sub-Forms

  • "by ref" vs. "by value"
  • what happens to changes in "by ref" sub-forms

Versions

  • Forms can have a specific version of a sub-form
form form version sub-form sub-form version
235 1 422 1
235 1 423 latest

Form & Sub-Forms

client side

Steps

  • the client gets a list of the requested form and its descendants.
  • reconstructs the full form.
  • analyzes paths for better performance.
  • recursive component draws the form.
{
    "label": "My Form",
    "fields": {
        "group_1": {
            "label": "Pregnancy",
            "fields": {
                "field_1": {
                    "label": "Breast feeding",
                    "path": "visit.0.orders.0.cbIsBreastfeeding"
                },
                "field_2": {
                    "label": "Pregnancy",
                    "path": "visit.0.orders.0.cbOPregnant"
                }
            }
        },
        "group_2": {
            "label": "Clinical Indications",
            "fields": {
                "field_1": {
                    "label": "Diabetic",
                    "path": "visit.0.orders.0.siteProtCOClinicalInd.0.cbIsSpoDiabetic"
                },
                "field_2": {
                    "label": "Asthmatic",
                    "path": "visit.0.orders.0.siteProtCOClinicalInd.0.cbIsSpoAsthmatic"
                }
            }
        }
    }
}

ViewModelAnalyzer - input

{
    "label": "My Form",
    "fields": {
        "group_1": {
            "path": "visit.0.orders.0",
            "label": "Pregnancy",
            "fields": {
                "field_1": {
                    "label": "Breast feeding",
                    "path": "cbIsBreastfeeding"
                },
                "field_2": {
                    "label": "Pregnancy",
                    "path": "cbOPregnant"
                }
            }
        },
        "group_2": {
            "path": "visit.0.orders.0.siteProtCOClinicalInd.0",
            "label": "Clinical Indications",
            "fields": {
                "field_1": {
                    "label": "Diabetic",
                    "path": "cbIsSpoDiabetic"
                },
                "field_2": {
                    "label": "Asthmatic",
                    "path": "cbIsSpoAsthmatic"
                }
            }
        }
    }
}

ViewModelAnalyzer - result

Data Flow

Redux inspired data flow

  • Single source of truth
  • Change history
  • ModelUpdater
  • Observable sub models
    • including calculations
  • angular2 change detection

 

 

Custom Components

Custom Components

  • Dynamically created (CD)
  • Model API:
    • @Model
    • ModelUpdater
  • @ContentComponent
    • inputs
      • configuration
      • model
      • layout
      • metadata
      • view-model
      • angular-form (useful for validations)
    • supported objects - TBD

Custom Pipes

TBD

Dynamic Forms Dev Concepts 2017

By risweb

Dynamic Forms Dev Concepts 2017

  • 414