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 HFWinJSCtrl.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' | 'not'; // default: 'equals'; only used by type field
cond?: IConditionExpression[]; // a nested condition
nestedOp?: 'and' | 'or'; // only used in nested conditions; default := and
}
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 it itself is fullfilled and 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 has not 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 an non empty value. -
else
is the state if 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 declarative in the FormDefinition. All alllowed 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 non of them is fullfilled, a defined 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 requirements 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 concenate several conditions by one operator ("op":"and"
/ "op":"or"
).
Conditions within a block
Within a block conditions use the control HFWinJSCtrl.Condition
. This control can be set to HTML areas by using the <div/>
tag.
<div id="tab-block#1">
<div id="condition1" data-win-control="HFWinJSCtrl.Condition"
data-hf-condition='{ "cond": [ { "type": "field", "id": "testradio1", "val": "yes" } ] }'>
<input id="text1" type="text" data-win-control="HFWinJSCtrl.TextField" />
</div>
<div id="condition2" data-win-control="HFWinJSCtrl.Condition"
data-hf-condition='{ "cond": [ { "type": "field", "id": "testradio1", "val": "no" } ] }'>
<input id="text1" type="text" data-win-control="HFWinJSCtrl.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-win-control="HFWinJSCtrl.TextField"
data-win-options="{ required: true }"
data-hf-condition='{ "cond": [ { "type": "field", "id": "testradio1", "val": "yes" } ],
"else": "optional" }'>
The field is always visible, but if the property required
is set to true, its required state depends on the defined condition. If the condition is fullfilled, the field is required.
<div id="testcombobox"
data-win-control="HFWinJSCtrl.ComboBox"
data-win-options="{
label: 'Test conditions',
minLength: 3,
dataTextField: 'name',
dataValueField: 'code',
dataSource: [
{ name: 'Selection 1', code: 'No. 01' },
{ name: 'Selection 2', code: 'No. 02' },
{ name: 'Selection 3', code: 'No. 03' },
{ name: 'Selection 41', code: 'No. 04' }
],
}"></div>
<input id="text2" type="text" data-win-control="HFWinJSCtrl.TextField"
data-win-options="{ required: true }"
data-hf-condition='{
"cond": [{
"type": "field",
"id": "testcombobox",
"val": "Selection 1" ,
"op":"not"
}],
"else": "optional"
}'>
If the selected value of the ComboBox is not the defined value, the condition is fullfilled and the field is required.
<input id="text3" type="text" data-win-control="HFWinJSCtrl.TextField"
data-win-options="{ required: true }"
data-hf-condition='{
"cond": [{
"type": "field",
"id": "testcombobox",
"val": "1",
"op":"contains"
}],
"else": "optional"
}'>
If the selected value of the ComboBox contains the defined value ('Selection 1' or 'Selection 41'), the condition is fullfilled and the field is required.
Conditions with multiple states (elseCallback
)
This function offers the possibility to 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"
}'>
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"
}'>
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.