Conditional Field Validation (Advanced)
Advanced rules and constraints on profile and relationship definition fields.
Clinia's Profiles and Relationship Definitions also provide condition validation rules for their properties. These rules (Similar to the ones exposed in the Field Validation documentation) are applied conditionally to another field's value.
Condition Validation Criteria
To specify when should a specific validation be in effect, the Clinia spec exposes a when
property that can be used to refer to another field property:
{
"properties": {
"<propertyKey>": {
"type": "...",
"rules": [
{
// All conditional rules
"when": {
// Specific Operators
}
},
{
// All conditional rules
"when": {
// Specific Operators
}
},
]
}
}
}
As seen above, multiple conditional validation criteria can also be specified on a single property. Something to keep in mind is that rules are applied as soon as their when
contained operator is evaluated to true
.
If we take our provider
for example, we can apply conditional validation rules such as "Specialities are required and must be at least one item if the Practice Number is specified":
{
"properties": {
"name": {
"type": "symbol"
},
"practiceNumber": {
"type": "integer"
},
"specialities": {
"type": "array",
"rules": [
// Conditional Rule with a "when" clause
{
"required": true,
"min": 1,
"when": {
"eq": {
"practiceNumber": "*" // Wildcard to test for the presence of a value
}
}
}
],
"items": {
"type": "symbol"
}
}
}
}
Allowed Operators
Property validation when
clause supports three main operators to test for a condition to be filled (a subset of the operators available as Search Operators).
Operator | Description |
---|---|
eq | An operation to test if the given property has the same value, or some equivalence (ex: Case insensitive for symbol type). The wildcard * can be used alone to test if the field has a value, or with text to test for partial match. |
lt | Only usable on date, time or numerical fields An operation to test if a property has a value lower or equal to a given one. |
gt | Only usable on date, time or numerical fields. An operation to test if a property has a value greater or equal to a given one. |
Nested Object Validation
For validation in nested objects, the properties mentioned in the when
clauses are built from the root of the profile.
This means that for a complex profile, you could build something like this to impose a emailCC
when the contact point is of type email
:
{
"properties": {
"details": {
"type": "object",
"properties": {
"contact": {
"type": "contactpoint",
"properties": {
"system": {
"rules": [
{
"required": true,
"enum": [
"phone",
"fax",
"email"
]
}
]
}
}
},
"emailCC": {
"type": "symbol",
"rules": [
{
"required": true,
"when": {
"eq": {
// Referring to the property from the root of the profile
"details.contact.system": "email"
}
}
}
]
}
}
}
}
}
Object Array Validation
Similar to the above, when using an operator on a property that is inside of an array, two choices are possible:
- If you want to test that ANY object/property of the array follows the clause, you can use the
[*]
clause (Inside or outside the array). - If you want to test against another property in the same object (Property with the rule must also be in the same object), you can use the
[current]
clause.
This could result in profile definitions such as:
Testing for the condition: "emailCC
is required if ANY contact point system
is of type "email"
":
{
"properties": {
"contacts": {
"type": "array",
"items": {
"type": "contactpoint"
},
"emailCC": {
"type": "symbol",
"rules": [
{
"required": true,
"when": {
"eq": {
// Referring to any items in "contacts"
"contacts[*].system": "email"
}
}
}
]
}
}
}
}
Testing for the condition: "value
must be defined if the contact
system
value is of type "email"
"
{
"properties": {
"contacts": {
"type": "array",
"items": {
"type": "contactpoint",
"properties": {
"value": {
"rules": [
{
"required": true,
"when": {
"eq": {
// Referring to the current item in "contacts"
"contacts[current].system": "email"
}
}
}
]
}
}
}
}
}
}
Updated 3 months ago