Forms
There are multiple layers that are considered form layers (e.g. the text box layer).
These layers have additional fields, most importantly the fields form
and formDataKey
. There are two ways in which a form can function, which is is determined by whether the form
is set for a layer. This is called a named form. Using form layers without a form
but using a formDataKey
is called an anonymous form.
The main difference between using a named form and an anonymous form is that the named form is app-wide, while the anonymous form is bound to the currently shown view. This means that if the current view is destroyed, the data in an anonymous form is cleared, while the the data in the named form persists until it is manually cleared.
The form can be thought of as a JSON object storing data, while the formDataKeys
are the keys in this object. Therefore, using the same formDataKey
multiple times in the same form leads to a synchronization of these form layers. Keep in mind that using the same formDataKey
in an insert layer layout will also result in this behavior.
It is also possible to influence the content of a form via actions:
- ResetForm will clear all values in a named form.
- ClearFormValue will delete a form value.
- SetFormValue will set a value to the specified
formDataKey
.
Change of behavior of the value field
It is important to know that the value
field works differently for form layers than for other layers. The value for a form layer should be seen as a fallback value rather than an actual value.
The priority with which a form layer receives its display value is:
- form value
- _settings value (given by the _settingsDataKey)
value
field
To set an initial value for a form layer, it is recommended to use the setFormValue action in combination with the viewCreated
event.
Reading from a form
You can access a form via evaluables in conditions, dynamicParams and dynamicValues.
The context
is different for named forms and anonymous forms. It is form
for anonymous forms and namedForm
for named forms. The value
is the formDataKey
for anonymous forms and formName:formDataKey
for named forms.
onChanged and valueActions
There are two ways to react to value changes inside a form layer, the onChanged actions and the valueActions.
onChanged: The onChanged actions are executed every time the value has changed. This can happen by user interaction (e.g. a user is typing in a textBox), but also by the setFormValue action.
valueActions: The valueActions are an array of action arrays. The appropriate action for the value is chosen by its index. Only possible for form layers, where values have an index (i.e. selectBox, checkBox and slider). These actions are only executed by direct user interaction and not by calling the setFormValue action.
Form validation
The primary way to validate a form is via a regular expression. Every form layer has validationExpression
field, which can be any regex.
With the validateForm action, every validationExpression
in the given form is checked, and only if all are valid, the onSuccess event is fired. Otherwise, the onError event is fired. You can also define a validationErrorMessage
on every form layer. After calling the validateForm action, the error message of the first invalid form layer is shown as a toast.
If you want to display something visibly in order to mark the user input as invalid while the user is typing, you should use layer conditions and use a regex check there in combination with the form. This is executed every time the user changes the input.
Examples
Goal: Have a login form with an email and a password textBox and use their values for a request.
{
"type": "textBox",
"name": "email",
"formDataKey": "email",
"inputType": "email"
},
{
"type": "textBox",
"name": "password",
"formDataKey": "password",
"inputType": "password"
},
{
"type": "container",
"name": "submitContainer",
"actions": [
{
"type": "request",
"leadingDelimiter": "{$",
"trailingDelimiter": "$}",
"dynamicParams": {
"email": {
"context": "form",
"field": "email"
},
"password": {
"context": "form",
"field": "password"
}
},
"params": {
"url": "$env(baseUrl)$/authenticate",
"contentType": "json",
"method": "POST",
"post": {
"email": "{$email$}",
"password": "{$password$}"
}
}
}
]
}
Goal: Have a selectBox for an insert item representing the amount of a product in a shopping cart.
{
"type": "selectBox",
"name": "amount",
"onChanged": [
{
"type": "setDelimiters",
"params": {
"leadingDelimiter": "{$",
"trailingDelimiter": "$}"
}
},
{
"type": "executeSQL",
"params": {
"sql": "UPDATE cart SET amount = ? WHERE id = ?;",
"sqlParams": [
"{$amount$}",
"{{id}}"
]
}
}
]
}
Goal: Have a checkbox representing the setting of receiving push notifications and send the value of the checkbox via a request to the backend on change.
{
"type": "checkBox",
"images": [
"{{uncheckedImage}}",
"{{checkedImage}}"
],
"values": [
"false",
"true"
],
"valueActions": [
[
{
"type": "request",
"params": {
"url": "$env(baseUrl)$/profile",
"method": "POST",
"contentType": "json",
"post": {
"pushEnabled": false
}
}
}
],
[
{
"type": "request",
"params": {
"url": "$env(baseUrl)$/profile",
"method": "POST",
"contentType": "json",
"post": {
"pushEnabled": true
}
}
}
]
]
}