Variables
To use variables, declare them in a separate variables
block in the card root. When declaring a variable, specify the following parameters:
name
: Name, which can consist of uppercase and lowercase Latin characters, digits, and the characters_
and.
. It can't start with a digit or a dot.type
: Type of variable. See Data types.value
: Default value.
For example:
{
"variables": [
{
"name": "subscribed",
"type": "boolean",
"value": true
}
],
}
Data types
Supported data types:
- Boolean:
boolean
- String:
string
- Integer:
integer
- Floating-point number:
number
- Color:
color
- Link to resource:
url
- Dictionary:
dict
- Array:
array
Examples of declaring variables
{
"variables": [
{
"name": "subscribed",
"type": "boolean",
"value": true
},
{
"name": "likes",
"type": "integer",
"value": 0
},
{
"name": "black",
"type": "color",
"value": "#f000"
},
{
"name": "username",
"type": "string",
"value": "unknown"
}
],
"states": [ ... ]
}
Dictionaries
One of the available variable types is dictionaries. These are custom JSON objects that can store variables of any other type.
For instance, dictionaries are useful for declaring palettes and retrieving their values depending on the app theme:
"variables": [
{
"name": "palette",
"type": "dict",
"value": {
"light": {
"text_color": "#ffffff",
"text_background": "#0077FF"
},
"dark": {
"text_color": "#000000",
"text_background": "#0077FF"
},
"big": {
"text_size": 20
},
"small": {
"text_size": 16
}
}
},
{
"name": "app_theme",
"type": "string",
"value": "light"
},
{
"name": "font_size",
"type": "string",
"value": "small"
}
]
Dictionaries can't identify types automatically, so you need to use appropriate functions to retrieve their values:
getIntegerFromDict(dict_name, path_to_value)
getNumberFromDict(dict_name, path_to_value)
getStringFromDict(dict_name, path_to_value)
getColorFromDict(dict_name, path_to_value)
getUrlFromDict(dict_name, path_to_value)
getBooleanFromDict(dict_name, path_to_value)
getOptIntegerFromDict(fallback, dict_name, path_to_value)
getOptNumberFromDict(fallback, dict_name, path_to_value)
getOptStringFromDict(fallback, dict_name, path_to_value)
getOptColorFromDict(fallback, dict_name, path_to_value)
getOptUrlFromDict(fallback, dict_name, path_to_value)
getOptBooleanFromDict(fallback, dict_name, path_to_value)
With the dictionary declared in the example, you can use color and font size values as follows:
"background": [
{
"type": "solid",
"color": "@{getColorFromDict(palette, app_theme, 'text_background')}"
}
],
"font_size": "@{getIntegerFromDict(palette, font_size, 'text_size')}",
"text_color": "@{getColorFromDict(palette, app_theme, 'text_color')}"
View an interactive example
Arrays
Arrays contain arbitrary JSON objects.
"variables": [
{
"type": "array",
"name": "array",
"value": [
"string",
123,
"@{expression}"
]
}
]
Same as dictionaries, arrays can't identify the types of their elements automatically, so you need to use appropriate functions to retrieve their values:
getIntegerFromArray(array, index)
getNumberFromArray(array, index)
getStringFromArray(array, index)
getColorFromArray(array, index)
getUrlFromArray(array, index)
getBooleanFromArray(array, index)
getArrayFromArray(array, index)
getDictFromArray(array, index)
getOptIntegerFromArray(array, index, fallback)
getOptNumberFromArray(array, index, fallback)
getOptStringFromArray(array, index, fallback)
getOptColorFromArray(array, index, fallback)
getOptUrlFromArray(array, index, fallback)
getOptBooleanFromArray(array, index, fallback)
getOptArrayFromArray(array, index, fallback)
getOptDictFromArray(array, index, fallback)
len(array)
Using an incorrect function type or attempting to access an index outside the bounds of the array will result in an error. To avoid this, consider using the getOpt*
function instead of get*
. In this case, the fallback
value will be returned instead of the error.
View an interactive example
Changing the values of variables
To change the value of a variable, use the set_variable
action. For example:
div-action://set_variable?name=common_text_size&value=17
To set the value for a variable, you can use calculated expressions and built-in functions.
You can also change the values of variables using the SDK (in Android using DivView#setVariable
).
Note
The type of a new value must match the variable type, otherwise the value can't be applied.
Examples:
-
Change the value of a floating-point variable:
div-action://set_variable?name=price&value=3.889
-
Change the value of a boolean variable:
true
:div-action://set_variable?name=is_liked&value=1
false
:div-action://set_variable?name=is_liked&value=0
-
Change the
color
type variable to green:div-action://set_variable?name=color_variable&value=@{encodeUri('#ff00ff00')}
Global variables
Variables that are declared within a layout are local and can't be accessed externally. To share variables between different layouts, use global variables.
To do this, declare a DivVariableController
object on the client side and pass it the variables that need to be accessed from the layout.
Example for Android
Declare DivVariableController
when creating DivConfiguration
:
val variableController = DivVariableController()
val configuration = DivConfiguration.Builder(imageLoader)
.divVariableController(variableController)
.build()
Now you can pass a variable to the controller. For example, let's pass the string variable app_theme
:
val theme = Variable.StringVariable("app_theme", "light")
variableController.putOrUpdate(theme)
Now all Div2View
created using this DivConfiguration
will have access to the app_theme
variable. You can change a variable's value via the DivVariable#set
method. If this variable is already declared in the controller, its value will also be updated.
Example for iOS
Declare DivVariableController
in DivKitComponents
:
let variablesStorage = DivVariablesStorage()
let divkitComponents = DivKitComponents(variablesStorage: variablesStorage)
Now you can pass a variable to the controller. For example, let's pass a dictionary with a palette:
let themeVariable: DivVariables = [
DivVariableName(rawValue: "palette"): .dict([
"text_color": "#ffffff",
"text_background": "#0077FF"
])
]
variablesStorage.put(themeVariable)
Now all Div2View
created using this DivKitComponent
will have access to the pallete
variable.
Example for Web
Create GlobalVariablesController
:
import {createVariable, createGlobalVariablesController} from '@divkitframework/divkit';
const controller = createGlobalVariablesController();
Now you can pass a variable to the controller. For example, let's pass a dictionary with a palette:
const palette = createVariable('palette', 'dict', {
"text_color": "#ffffff",
"text_background": "#0077FF"
});
controller.setVariable(palette);
Now all class instances created using this controller
will have access to the pallete
variable.
Alert
Local variables are given precedence over global ones. If you declare a local variable that shares the same name as a global one, the global variable will be inaccessible. In addition, modifying a global variable from a layout changes it in DivVariableController
, which means the variable will also change for all other layouts where it's used.
Running actions when changing variable values
When changing the variable value (except for updating all properties where the variable is used), any number of actions can be run. Add the trigger description in variable_triggers
:
-
condition
: A condition for running the action. It can contain a boolean expression using variables or trigger events. -
mode
: Determines when the action triggers:on_condition
: The action is triggered when a change in the variable results in a certain condition being met (the condition wasn't met until the action occurred).on_variable
: The action is triggered every time the condition is met when the value of the variable changes.
For example, suppose the variables change several times, with
condition
returningtrue → true → false → true
. When usingon_condition
, the action triggers two times, while withon_variable
it triggers three times. -
actions
: Describes actions that must be run when the condition is met.
Limitations:
- Conditions that don't contain variables (such as
"condition": "@{1 == 1}"
) or contain functions that don't depend on variables won't work, because variables determine when to run the condition check. - The trigger won't start if the compared entities in the condition have different types (for example, if a boolean variable is compared with an
integer
variable).
For example:
{
"states": { ... },
"variables": { ... },
"variable_triggers": [
{
"condition": "@{liked}",
"actions": [
{
"url": "div-action://set_variable?name=total_likes&value=@{sum(total_likes, 1)}"
}
]
},
{
"condition": "@{subscribed && !liked}",
"mode": "on_condition",
"actions": [
{
"url": "div-action://set_state?state_id=0/subscriptions/expanded"
},
{
"log_id": "common_posts_shown",
"url": "div-action://set_state?state_id=0/common_posts/collapsed"
}
]
},
{
"condition": "@{total_likes > 100 || user_name == 'John'}",
"mode": "on_variable",
"actions": [ ... ]
}
]
}
In the example above, the first trigger runs the action that increases the total_likes
variable value each time the liked
variable value changes from false
to true
. The second trigger follows the same logic.
Because of the "mode": "on_variable"
parameter, the third trigger fires every time the variable values are changed and the condition
is met.
Methods
For working with arrays and dictionaries, it's convenient to use methods. Unlike functions, methods are called directly from an array or dictionary and return the required value.
Available methods
Name |
Description |
Result type |
|
Converts the value of a variable of any type to a string. |
|
|
Allows you to get an array from a dictionary (array) by key (index). |
|
|
Allows you to get a dictionary from a dictionary (array) by key (index). |
|
|
Allows you to get a boolean value from a dictionary (array) by key (index). |
|
|
Allows you to get a color value from a dictionary (array) by key (index). |
|
|
Allows you to get an integer from a dictionary (array) by key (index). |
|
|
Allows you to get a floating-point number from a dictionary (array) by key (index). |
|
|
Allows you to get a string from a dictionary (array) by key (index). |
|
|
Allows you to get a URL from a dictionary (array) by key (index). |
|
|
Checks if an array (dictionary) is empty and returns the corresponding boolean value. |
|
Complete descriptions of method fields and usage examples are available in the DivKit repository:
Field values
The method description includes the following fields:
-
function_name
— method name. -
is_method
— flag indicating whether the function is a method. For all methods, it has the valuetrue
. -
doc
— description of how the method works. -
arguments
— list of arguments. Each argument is described by the values:-
type
— type; -
doc
— description; -
vararang
— optional flag allowing this argument to accept not one, but multiple values of the required type.
-
-
result_type
— type of the returned value.
View an interactive example
Element-level variables
Element-level variables are declared in the layout within the element they characterize.
Note
Previously, only card-level variables (for the card
object) could be declared. Now variables can be declared for any element.
View an interactive example
Element-level triggers
Element-level triggers are activated when the value of an element-level variable changes. Their format is the same as for global triggers.
An element-level trigger:
-
has access to element-level variables of the parent object;
-
is triggered even for invisible elements (with the parameter
"visibility" = "gone"/"invisible"
); -
is not triggered in states and tabs that are not currently active.
When transitioning to a new state or another tab:
-
if the state (tab) is activated for the first time, the trigger fires when the condition in
condition
is met; -
if the state (tab) has already been initialized and the condition was not met before exiting it, the trigger will fire when the condition starts to be met.
View an interactive example
Learn more
Follow DivKit news in the Telegram channel: http://t.me/divkit_news
You can also discuss topics of interest in the DivKit user community in Telegram: https://t.me/divkit_community_ru