Conditions
Control the visibility and validation of form elements by adding conditions. These conditions can control the visibility of structural form elements as there are pages, tabs and blocks and the behaviour of a form field.
Therefore simply add the attribute data-hf-condition
to the navigation elements and the Form Controls or use the form control Condition
.
Even the submission of the form can be controlled by adding a structural condition to the <form>
-tag.
Definition​
The value of the data-hf-condition
must be a JSON string.
The typescript representation of the condition object is defined below:
interface IConditionExpression {
type: 'page' | 'tab' | 'block' | 'field' | 'kiosk' | 'stage';
id: string;
val?: boolean | number | string; // only used by type field
op?:
| 'equals'
| 'contains'
| 'doesnotcontain'
| 'startswith'
| 'doesnotstartwith'
| 'endswith'
| 'doesnotendwith'
| 'regexp'
| 'not'
| 'gt'
| 'gte'
| 'lt'
| 'lte'; // default: 'equals'; only used by type field
regexpOp?: string; // only used if op=regexp
cond?: IConditionExpression[]; // a nested condition
nestedOp?: 'and' | 'or'; // only used in nested conditions; default := and
fullfillMissingField?: boolean; // Fullfill condition if field is missing in form structure
}
interface IElseCondition {
cond?: IConditionExpression[];
default?: boolean;
op?: 'and' | 'or';
}
interface IConditionExpressionElseComplex {
readonly: IElseCondition;
disabled: IElseCondition;
invisible: IElseCondition;
optional: IElseCondition;
}
interface ICondition {
cond: IConditionExpression[];
op?: 'and' | 'or'; // default: and
else?: 'invisible' | 'disabled' | 'readonly' | 'optional' | IConditionExpressionElseComplex;
elseCallback?: (executorId: string, conditionObject: ICondition) => string;
excludeFromValidation?: boolean; // default: false
}
- A structural condition (el:
page
,tab
orblock
) is fullfilled when all its required fields are filled out and all fields are valid.
-
A
field
condition is fullfilled when the op isequals
(default) and the field has the valueval
. Afield
condition is fullfilled when the op isnot
and the field does not have the same value as defined inval
. Afield
condition is fullfilled when the op iscontains
and the field contains the value that is defined inval
. -
A
field
condition without propertyval
is fullfilled if the field has a non empty value. -
else
is the state when the condition is not fullfilled. The default isinvisible
.invisible
structural element or control is hidden. Required fields are not counted as required.disabled
structural element or control is visible but disabled. Required fields are not counted as required.optional
structural element or control is visible and enabled. Required fields are not counted as required.readonly
structural element or control is visible and readonly. Required fields are not counted as required.
-
elseCallback
is used to define a callback function which have to return one of the above else states as string. -
excludeFromValidation
prevents the validator from validating a condition again within the same condition validation. This should only be used in special cases where otherwise a condition loop will be the result. Don't use required fields within such a condition.
Please mind the difference between "disabled" and "readonly", especially in case of structural elements. The status "readonly" preserves the navigability of the structural element ( i.e. "page", "tab") and offers a better readability than the status "disabled".
FormControls with boolean values (CheckBox, RadioBox, Switch) ​​must have a default value in order to work properly as Condition field!
The option "disabled" is deprecated and only supported for backwards compatibility of versions lower than 7.3.0.
Complex else state​
Else states can also be defined in the FormDefinition. All allowed else states can be used as keys with normal condition objects as values. Nested conditions can be used as well.
If one of the conditions is fullfilled, this else state is used for the main condition. If none of them is fullfilled, a predefined default else state is used.
<li
data-hf-title="Service Notes"
data-hf-condition='{
"cond": [{
"type": "stage",
"id": "S1",
"val": false
}],
"else": {
"readonly": {
"op": "and",
"cond": [{
"type": "field",
"id": "operation_id",
"val": "1234"
}, {
"cond": [{
"type": "stage",
"id": "S1",
"val": true
}, {
"type": "stage",
"id": "S3",
"val": true
}],
"nestedOp": "or"
}]
},
"invisible": {
"default": true
}
}
}'
>
...
</li>
Conditions on structural elements​
The attribute data-hf-condition
can be added to every HybridForms structural element like page, tab or block and on the form itself.
Conditions defined in the form
tag are required for the approval of the form itself. Conditions on pages can be based on all structural elements as well as on particular fields.
<form data-hf-condition='{ "cond": [ { "type" : "page", "id": "lastpage" } ] }'>
<!-- first level - pages -->
<ol>
<li
data-hf-title="Controls"
data-hf-condition='{
"op" : "and",
"cond": [{
"type" : "field",
"id": "testradio",
"val": "value1"
}, {
"type" : "field",
"id": "testcheckbox",
"val": "yes"
}],
"else": "optional"
}'
>
<!-- second level - tabs -->
<ol>
...
</ol>
</li>
<!-- nested condition on the last page -->
<li
data-hf-title="Last Page"
id="lastPage"
data-hf-condition='{
"op": "or",
"cond": [{
"type": "stage",
"id": "ST2",
"val": true
}, {
"type": "stage",
"id": "ST4",
"val": true
}, {
"cond": [{
"type": "field",
"id": "address_zip_code",
"val": "8010"
}, {
"type": "field",
"id": "address_city",
"val": "Graz"
}],
"nestedOp": "or"
}],
"else": "invisible"
}'
>
<!-- second level - tabs -->
<ol>
...
</ol>
</li>
</ol>
</form>
Conditions defined in the navigation elements can control the visibility or disable/enable editing of a page, a tab or a block.
The condition inside the <form>
-tag is fulfilled if the required fields of the page "lastpage" are filled in, otherwise the App bar button "Submit" is disabled. Assure the page's ID is set and unique!
You can only define one conditional state (else
) per element but you can connect several conditions by one operator ("op":"and"
/ "op":"or"
).
Conditions within a block​
Within a block conditions use the control Condition
. This control can be set to HTML areas by using the <div/>
tag.
<div id="tab-block#1">
<div
id="condition1"
data-hf-control="Condition"
data-hf-condition='{ "cond": [ { "type": "field", "id": "testradio1", "val": "yes" } ] }'
>
<input id="text1" type="text" data-hf-control="TextField" />
</div>
<div
id="condition2"
data-hf-control="Condition"
data-hf-condition='{ "cond": [ { "type": "field", "id": "testradio1", "val": "no" } ] }'
>
<input id="text1" type="text" data-hf-control="TextField" />
</div>
</div>
For further details on the control please refer to the corresponding entry in the chapter "Form controls".
Conditions within a field​
Just add the data-hf-condition
attribute to the field:
<input
id="text1"
type="text"
data-hf-control="TextField"
data-hf-options="{
required: true
}"
data-hf-condition='{
"cond": [{
"type": "field",
"id": "testradio1",
"val": "yes"
}],
"else": "optional"
}'
/>
In the example above the else state "optional" means that a required field looses the required status if the condition is not met, its required state depends on the defined condition. If the condition is fullfilled, the field is required. This else state makes only sense on controls that has the required property set to true in the data-hf-options attribute.
Special Condition Operators on Fields​
<input
id="textfield01"
type="text"
data-hf-control="TextField"
data-hf-options="{
label: 'String Cond Target',
tooltip: 'Das ist ein Tooltip',
onChanged: HFFormdefinition.Playground.doSomethingOnChange
}"
/>
<input
id="tab2-textfield01"
type="text"
data-hf-control="TextField"
data-hf-condition='{
"cond": [{
"type": "field",
"id": "textfield01",
"val": "foo",
"op": "not"
}],
"else": "readonly"
}'
data-hf-options="{
label: 'Not "foo"',
tooltip: 'This condition is fullfilled if the value is not "foo"',
required: false
}"
/>
/>
In the example above there is the property op
defined on the cond
object. This op
property defines how the given val
property is evaluated. In the case of "op": "not"
the condition is fullfilled if the field value is not "foo".
There are different options for the op value, default is equals
: A condition is fullfilled if the given val
value is equal to the field value.
General Operators:​
Operator | Description |
---|---|
equals | A condition is fullfilled if the given val value is equal to the field value. This is the default operation and does not have to be defined. |
not | A condition is fullfilled if the field value is not the defined value in the cond object. |
Operator for field values of type string:​
Operator | Description |
---|---|
contains | A condition is fullfilled if the defined value is contained in the field value. |
doesnotcontain | A condition is fullfilled if the defined value is not contained in the field value. |
startswith | A condition is fullfilled if the field value starts with the defined value in the cond object. |
doesnotstartwith | A condition is fullfilled if the field value does not start with the defined value in the cond object. |
endswith | A condition is fullfilled if the field value ends with the defined value in the cond object. |
doesnotendwith | A condition is fullfilled if the field value does not end with the defined value in the cond object. |
regexp | A condition is fullfilled if the regexp defined in the val property returns true for the field value. To define the regexp you have to use the additional regexpOp property in the cond object. See the example below on how to use the regexp operator |
Exmaple: Use of Regexp Operator​
<input
id="tab2-textfield2-4"
type="text"
data-hf-control="TextField"
data-hf-condition='{
"cond": [{
"type": "field",
"id": "textfield01",
"val": "foo",
"op": "regexp",
"regexpOp": "foo\\d{2}"
}],
"else": "readonly"
}'
data-hf-options="{
label: 'regexp "foo\\d{2}"',
tooltip: 'Condition ist erfüllt, wenn der Text String "foo" und zwei Zahlen enthält',
required: false
}"
/>
Operator for field values of type number:​
Operator | Description |
---|---|
gt | A condition is fullfilled if field value is greater than the defined value. |
gte | A condition is fullfilled if field value is greater than or equal to the defined value. |
lt | A condition is fullfilled if field value is less than the defined value. |
lte | A condition is fullfilled if field value is less than or equal to the defined value. |
Conditions with multiple states (elseCallback
)​
This function offers the possibility for different states of a structural element or control in line with "stages" in case of more than two possible values.
Note: This option is only an "initial" condition. The condition is not applied while editing!
<li
data-hf-title="Service Data"
data-hf-condition='{
"cond": [{
"type": "stage",
"id":"S1",
"val": true
}],
"elseCallback": "HFFormdefinition.DemoQAStagesHelpers.getElseStatePage"
}'
></li>
export function getElseStatePage() {
let currStage = HybridForms.API.Stages.getFormStage();
// return 'readonly';
switch (currStage) {
case 'S3':
return 'readonly';
default:
return 'invisible';
}
}
The Custom Code example (getElseStatePage()
) defines the default
- state (else-invisible
) and further else states of the page "Service data" depending on the active stage.
Nested Conditions​
This function offers the possibility to nest conditions, to set up more complex conditions.
<li
data-hf-title="Service Data"
data-hf-condition='{
"op": "or",
"cond": [{
"type": "stage",
"id": "ST1",
"val": true
}, {
"cond": [{
"type": "field",
"id": "address_zip_code"
}, {
"type": "field",
"id": "address_city"
}],
"nestedOp": "or"
}],
"else": "invisible"
}'
></li>
In the example above the condition validates to true if the form is in stage 1 or one of the two defined fields has a value.