---
metadata:
  - name: generator
    content: Diplodoc Platform v5.50.3
alternate:
  - https://divkit.tech/docs/en/concepts/interaction.md
  - https://divkit.tech/docs/ru/concepts/interaction.md
---
> **Documentation Index:** Fetch the complete configuration index at https://divkit.tech/docs/en/llms.txt

# Actions with elements

When the user taps the card, [action](https://divkit.tech/docs/en/concepts/divs/2/div-action.md) is triggered.

```json translate=no
{
  "actions": [{
    "log_id": "<unique_id>",
    "url": "div-action://<action_description>?other/parameters"
  }]
}
```

#|
||
**Parameter**
|
**Description**
||
||
`url`
|
An event that is triggered by tapping the card.
||
||
`log_id`
|
Logging ID. It must be unique within a single card.
||
|#

You can open the menu by tapping using the special `menu_items` parameter. If at least one action in the array has a `menu_items` field, tapping the element will show a menu, and all other fields will be ignored.

{% note info %}

Menu items with `is_enabled: false` or without active actions are not displayed in the menu. Only menu items that have at least one enabled action are displayed.

{% endnote %}

Actions can be bound to different types of gestures:
- `actions` - triggered by a regular tap
- `longtap_actions` - triggered by a long press
- `doubletap_actions` - triggered by a double tap
- `press_start_actions` - triggered at the start of a press (for example, when pressing a slider thumb)
- `press_end_actions` - triggered at the end of a press (for example, when releasing a slider thumb)

{% note info %}

When tapping on a child element with actions, container actions are not triggered. Child element actions have priority over container actions.

{% endnote %}

## Typed actions {#typed-actions}

Typed actions differ from standard actions in format. They can be specified in a JSON object. In standard actions, all parameters must be specified in the `url` field.

#|
|| **Action example** | **Typed action example** ||
||
```json
"actions": [
  {
    "log_id": "set_2",
    "url": "div-action://set_variable?name=variable&value=123"
  }
]
```
|
```json
"actions": [
  {
    "log_id": "set_2",
    "typed": {
      "type": "set_variable",
      "variable_name": "variable",
      "value": {
        "type": "integer",
        "value": 123
      }
    }
  }
]
```
||
|#

{% note tip %}

We recommend using typed actions. They allow you to avoid encoding parameters and simplify visual perception and layout validation.

{% endnote %}

#|
|| **Name** | **Description** ||
|| [div-action-animation-start](https://divkit.tech/docs/en/concepts/divs/2/div-action-animator-start.md) | Starts the specified animator. ||
|| [div-action-animation-stop](https://divkit.tech/docs/en/concepts/divs/2/div-action-animator-stop.md) | Stops the specified animator. ||
|| [div-action-array-insert-value](https://divkit.tech/docs/en/concepts/divs/2/div-action-array-insert-value.md) | Adds a value to an array. ||
|| [div-action-array-remove-value](https://divkit.tech/docs/en/concepts/divs/2/div-action-array-remove-value.md) | Removes a value from an array. ||
|| [div-action-array-set-value](https://divkit.tech/docs/en/concepts/divs/2/div-action-array-set-value.md)| Sets a value in an array by index. ||
|| [div-action-focus-element](https://divkit.tech/docs/en/concepts/divs/2/div-action-focus-element.md) | Requests focus for an element. For text input fields, when called again on an already focused field, the cursor moves to the end of the text. ||
|| [div-action-clear-focus](https://divkit.tech/docs/en/concepts/divs/2/div-action-clear-focus.md) | Removes focus from an element. ||
|| [div-action-set-cursor-position](https://divkit.tech/docs/en/concepts/divs/2/div-action-set-cursor-position.md) | Sets cursor position in an input field. ||
|| [div-action-copy-to-clipboard](https://divkit.tech/docs/en/concepts/divs/2/div-action-copy-to-clipboard.md) | Copies data to the clipboard. ||
|| [div-action-dict-set-value](https://divkit.tech/docs/en/concepts/divs/2/div-action-dict-set-value.md) | Sets a value in a dictionary by key. ||
|| [div-action-download](https://divkit.tech/docs/en/concepts/divs/2/div-action-download.md) | Downloads additional data in `div-patch` format and updates the current element. ||
|| [div-action-show-tooltip](https://divkit.tech/docs/en/concepts/divs/2/div-action-show-tooltip.md) | Shows a tooltip. ||
|| [div-action-hide-tooltip](https://divkit.tech/docs/en/concepts/divs/2/div-action-hide-tooltip.md) | Hides a tooltip. ||
|| [div-action-scroll-by](https://divkit.tech/docs/en/concepts/divs/2/div-action-scroll-by.md) | Scrolls a scrollable container from the current position by the specified `item_count` or `offset` value. ||
|| [div-action-scroll-to](https://divkit.tech/docs/en/concepts/divs/2/div-action-scroll-to.md) | Scrolls to a position or switches an element in a container to the specified `destination` value. Supports `item_id` destination for scrolling to an element by its identifier. ||
|| [div-action-set-state](https://divkit.tech/docs/en/concepts/divs/2/div-action-set-state.md) | Sets a new appearance for content in `div-state`. ||
|| [div-action-set-stored-value](https://divkit.tech/docs/en/concepts/divs/2/div-action-set-stored-value.md) | Temporarily stores a variable in storage. ||
|| [div-action-set-variable](https://divkit.tech/docs/en/concepts/divs/2/div-action-set-variable.md) | Assigns a value to a variable. ||
|| [div-action-submit](https://divkit.tech/docs/en/concepts/divs/2/div-action-submit.md) | Sends variables from a container via a link. Data sending configuration can be determined by the host application. By default, variables are passed in the request body as JSON, request method is POST. ||
|| [div-action-timer](https://divkit.tech/docs/en/concepts/divs/2/div-action-timer.md) | Controls a timer. ||
|| [div-action-update-structure](https://divkit.tech/docs/en/concepts/divs/2/div-action-update-structure.md) | Sets values in a variable of type array or dictionary with different nesting. ||
|| [div-action-video](https://divkit.tech/docs/en/concepts/divs/2/div-action-video.md) | Controls video playback. ||
|| [div-action-custom](https://divkit.tech/docs/en/concepts/divs/2/div-action-custom.md) | Executes a custom action with user data. ||
|#

## Sets of states {#states}

The [state](https://divkit.tech/docs/en/concepts/divs/2/div-state.md) element switches the appearance of content. You can use it to add:

- Buttons that change their state (for example, the like icon when tapped).
- Content that can be expanded (for example, a bridge card or a geo block).

One picture changes to another, but the user sees it as an interaction.

### Actions on div-state elements {#state-actions}

The `div-state` element itself supports all standard action properties, allowing you to add interactive behavior directly to the state container:

- `actions`: Actions triggered when clicking on the state element
- `longtap_actions`: Actions triggered when long-pressing the state element
- `doubletap_actions`: Actions triggered when double-clicking the state element
- `press_start_actions` / `press_end_actions`: Actions triggered at the start/end of a press
- `hover_start_actions` / `hover_end_actions`: Actions triggered when hovering over the element

{% note info %}

The `press_start_actions` and `press_end_actions` properties are especially useful for components with continuous interaction, such as sliders, where it's important to track the beginning and end of the drag gesture.

{% endnote %}

{% cut "Example: div-state with actions" %}

```json
{
  "type": "state",
  "div_id": "interactive_state",
  "states": [
    {
      "state_id": "default",
      "div": {
        "type": "text",
        "text": "Click me to change state"
      }
    },
    {
      "state_id": "clicked",
      "div": {
        "type": "text",
        "text": "State changed!"
      }
    }
  ],
  "actions": [
    {
      "log_id": "state_click",
      "url": "div-action://set_state?state_id=0/interactive_state/clicked"
    }
  ],
  "longtap_actions": [
    {
      "log_id": "state_long_press",
      "url": "div-action://set_variable?name=long_pressed&value=true"
    }
  ]
}
```

{% endcut %}

This allows you to create more complex interactive behaviors where the state container itself responds to user interactions, in addition to the individual elements within each state.

To switch to a different state, use `url`:

```translate=no
div-action://set_state?state_id=<div_data_state_id/div_id/state_id>&temporary=<bool>
```

The path is formed from the hierarchy root:

#|
||
**Parameter**
|
**Description**
||
||
`state_id`
|
The path of the state inside `state` that needs to be activated. Set in `div_data_state_id/div_id/state_id` format.

Can be hierarchical: `div_data_state_id/div_id_1/state_id_1/../div_id_n/state_id_n`
Consists of:
- `div_data_state_id`: `state_id` numeric value of the `state` object in [data](https://divkit.tech/docs/en/concepts/divs/2/div-data.md).
- `div_id`: `div_id` value of the `state` object.
- `state_id`: `state_id` value of the ``state`` object in [state](https://divkit.tech/docs/en/concepts/divs/2/div-state.md).
||
||
`temporary`
|
Indicates a state change:

- `true`: The change is temporary and the state will revert to the original one when the element is re-created (default value).
- `false`: The state change is permanent.
||
|#


{% cut "View an interactive example" %}


<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/interaction_1.json" width="700" height="500" frameborder="1"></iframe>


{% endcut %}


### Empty state {#empty}

If you need to hide a block, don't add a `div` field, but specify `"state_id": "empty"`.

![](../_images/create-card/empty-state-anim.gif =360x)

{% cut "View an interactive example" %}


<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/interaction_2.json" width="700" height="500" frameborder="1"></iframe>


{% endcut %}


### Nested states {#nested}

If multiple states are nested in each other, write the full path from the root in order to switch:
```translate=no
div-action://set_state?state_id=[root state id]/[element's div_id]/[state's state_id]
```


{% cut "View an interactive example" %}


<iframe src="https://yastatic.net/s3/home/divkit/docs/1.0.8/index.html?url=https://yastatic.net/s3/home/divkit/doc_samples/common/interaction_3.json" width="700" height="500" frameborder="1"></iframe>


{% endcut %}


## Actions when appearing {#visibility}

[visibility](https://divkit.tech/docs/en/concepts/divs/2/div-visibility-action.md) elements are triggered when an element is shown on the screen.

```json translate=no
{
  "visibility_actions": [
    {
      "log_id":"content_01_visibility",
      "visibility_percentage": 100,
      "visibility_duration": 1000,
      "url": "div-action://none"
    }
  ]
}
```

#|
||
**Parameter**
|
**Description**
||

||
`visibility_percentage`
|
Percentage of the element's visible area.
||

||
`visibility_duration`
|
The minimum time of its visibility.
||
|#



## Loading more data {#loading-data}

To load more data in the form of a [patch](https://divkit.tech/docs/en/concepts/divs/2/div-patch.md) and update the current element, specify the `download` action:

```translate=no
div-action://download?url=<patch_url>
```

#|
||
**Parameter**
|
**Description**
||

||
`url`
|
URL to get the patch.
||
|#


Response format:

```json translate=no
{
  "patch": {
    // data in patch format
  },
  "templates": {
    // templates that can be used in the patch section
  }
}
```

{% note info %}

To use patches on Android, pass a `DivDownloader` implementation to your `DivConfiguration`.

{% endnote %}

## Switching elements {#switch-elements}

To navigate inside [gallery](https://divkit.tech/docs/en/concepts/divs/2/div-gallery.md), [pager](https://divkit.tech/docs/en/concepts/divs/2/div-pager.md), and [tabs](https://divkit.tech/docs/en/concepts/divs/2/div-tabs.md), specify an action:

- `set_current_item`: For the current element.
- `set_next_item`: For the next element.
- `set_previous_item`: For the previous element.

```translate=no
div-action://set_current_item?id=<div_id>&item=<item_index>
div-action://set_next_item?id=<div_id>&overflow=<clamp|ring>
div-action://set_previous_item?id=<div_id>&overflow=<clamp|ring>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
ID of the element in which the current one must be switched.
||

||
`item`
|
Index of the element to scroll to.
||

||
`overflow`
|
Specifies how navigation will occur when the boundary elements are reached:

- `clamp`: Stop switching at the boundary element (default value).
- `ring`: Switch to the start or end depending on the current element.
||
|#

### Jump to the start or end of the gallery

To jump to the start or end of the [gallery](https://divkit.tech/docs/en/concepts/divs/2/div-gallery.md), specify the following action:

```translate=no
div-action://scroll_to_start?id=<div_id>
div-action://scroll_to_end?id=<div_id>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
ID of the element in which the current one must be switched.
||
|#

If the elements inside `gallery` are bigger than the gallery itself, the `scroll_to_end` action scrolls it to the end of the last element.

### Scroll the gallery several dp forward or backward, or to a specific value

To scroll the [gallery](https://divkit.tech/docs/en/concepts/divs/2/div-gallery.md) forward or backward, specify the following action:

```translate=no
div-action://scroll_forward?id=<div_id>&step=<dp_count>&overflow=<clamp|ring>
div-action://scroll_backward?id=<div_id>&step=<dp_count>&overflow=<clamp|ring>
```

To scroll the [gallery](https://divkit.tech/docs/en/concepts/divs/2/div-gallery.md) to a specific value, specify the following action:

```translate=no
div-action://scroll_to_position?id=<div_id>&step=<dp_count>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
ID of the element in which the current one must be switched.
||

||
`step`
|
Value in [dp](https://en.wikipedia.org/wiki/Device-independent_pixel) representing either the position to scroll the gallery to or the scroll step, depending on the action.
||

||
`overflow`
|
Specifies how navigation will occur when the boundary elements are reached:

- `clamp`: Stop switching at the boundary element (default value).
- `ring`: Switch to the start or end depending on the current element.
||
|#


## Setting cursor position {#set-cursor-position}

To set the cursor position in an input field, use the typed action `set_cursor_position`:

{% cut "View example" %}

```json translate=no
{
  "log_id": "set_cursor",
  "typed": {
    "type": "set_cursor_position",
    "id": "input_1",
    "position": {
      "type": "absolute",
      "start": 0,
      "end": -1
    }
  }
}
```

{% endcut %}

#|
||
**Parameter**
|
**Description**
||
||
`id`
|
Input field identifier.
||
||
`position`
|
Object with position parameters:
- `type`: `"absolute"` (only supported type)
- `start`: starting position (required, number)
- `end`: ending position (optional, number)

If `end` is not specified or equals `start` - cursor position is set. If `end` differs from `start` - text is selected. Value `-1` indicates the end of the text.
||
|#

## Managing tooltips {#managing-tooltips}

To show or hide tooltips, specify the `show_tooltip` or `hide_tooltip` action:

```translate=no
div-action://show_tooltip?id=<tooltip_id>
div-action://hide_tooltip?id=<tooltip_id>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
Tooltip ID.
||
|#



## Video controls {#video}

To control a [video](https://divkit.tech/docs/en/concepts/video.md), use the `video` action:

```translate=no
div-action://video?id=video_id&action=<start|pause>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
ID of an element with a video.
||

||
`action`
|
Actions with videos:

- `start`: Resume playback.
- `pause`: Pause.
||
|#

## Timer controls {#timer}

To control a [timer](https://divkit.tech/docs/en/concepts/timer.md), use the `timer` action:

```translate=no
div-action://timer?action=<action>&id=<id>
```

#|
||
**Parameter**
|
**Description**
||

||
`id`
|
Timer ID.
||

||
`action`
|
Actions with timers:

- `start`: Start the timer.
- `stop`: Stop the timer.
- `pause`: Pause the timer.
- `resume`: Resume the timer.
- `cancel`: Interrupt the timer.
- `reset`: Reset the timer.
||
|#

## Changing the values of variables {#variables-values}

To change the value of [variables](https://divkit.tech/docs/en/concepts/variables.md), specify the `set_variable` action:

```translate=no
div-action://set_variable?name=<variable_name>&value=<new_value>
```
#|
||
**Parameter**
|
**Description**
||

||
`name`
|
Variable name.
||

||
`value`
|
New value.
||
|#


## Saving variables to temporary storage

To temporarily store variable values, specify the `set_stored_value` action:

```translate=no
div-action://set_stored_value?name=<variable_name>&value=<new_value>&type=<variable_type>&lifetime=<lifetime_in_sec>
```

#|
||
**Parameter**
|
**Description**
||

||
`name`
|
Variable name.
||

||
`value`
|
Value to save.
||

||
`type`
|
Variable type. Must be `string`, `number`, `integer`, `url`, or `color`.
||

||
`lifetime`
|
Variable's storage lifetime in seconds. If you attempt to retrieve the variable after this time, it will be considered expired.
||
|#

To get the value of a stored variable, use calculated expressions:

```translate=no
@{getStoredStringValue(name, default)}
@{getStoredNumberValue(name, default)}
@{getStoredIntegerValue(name, default)}
@{getStoredUrlValue(name, default)}
@{getStoredColorValue(name, default)}
```

The `name` parameter still represents the name of the stored variable, and `default` is the value to return if the variable can't be found or has expired.

## Custom actions {#custom-actions}

Custom actions allow you to execute custom logic that is not covered by standard DivKit actions. They pass arbitrary data (payload) to the host application for processing.

### Using custom actions

To create a custom action, specify the type `"custom"` and pass the required data in the `payload` field:

```json
"actions": [
  {
    "log_id": "custom_action_1",
    "typed": {
      "type": "custom"
    },
    "payload": {
      "action_type": "open_profile",
      "user_id": "12345",
      "additional_data": "custom_value"
    }
  }
]
```

### Handling custom actions in iOS

To handle custom actions in an iOS application, you need to:

1. Implement the `DivCustomActionHandling` protocol:

```swift
class MyCustomActionHandler: DivCustomActionHandling {
  func handle(
    payload: DivDictionary,
    context: DivActionHandlingContext,
    sender: AnyObject?
  ) {
    // Handle custom action
    if let actionType = payload["action_type"] as? String {
      switch actionType {
      case "open_profile":
        if let userId = payload["user_id"] as? String {
          // Open user profile
          openUserProfile(userId: userId)
        }
      default:
        break
      }
    }
  }
}
```

2. Pass the handler to the DivKit configuration:

```swift
let divKitComponents = DivKitComponents(
  customActionHandler: MyCustomActionHandler(),
  // ... other parameters
)
```

### Custom action parameters

#|
||
**Parameter**
|
**Description**
||
||
`payload`
|
An arbitrary dictionary of data that is passed to the host application for processing. Can contain any custom fields.
||
|#

{% note tip %}

Custom actions are useful for implementing specific business logic that is not included in the standard set of DivKit actions, such as navigation between application screens, calling specific APIs, or integration with native modules.

{% endnote %}

## Order of evaluation of expressions in actions {#evaluation-order}

The `is_enabled` and action parameter expressions are evaluated immediately before each action is executed.

{% cut "Example" %}

```json translate=no
"actions": [
  {
    "log_id": "1",
    "is_enabled": "@{enable_actions}",
    "typed": {
      "type": "set_variable",
      "variable_name": "counter",
      "value": {
        "type": "integer",
        "value": 5
      }
    }
  },
  {
    "log_id": "2",
    "is_enabled": "@{counter > 0}",
    "typed": {
      "type": "set_variable",
      "variable_name": "message",
      "value": {
        "type": "string",
        "value": "Done"
      }
    }
  },
  {
    "log_id": "3",
    "is_enabled": "@{message != ''}",
    "typed": {
      "type": "set_variable",
      "variable_name": "result",
      "value": {
        "type": "string",
        "value": "@{message}"
      }
    }
  }
]
```

If the `counter` variable is initially `0`, but the first action sets the `counter` value to `5`, then the second action will be executed because its `is_enabled` is checked after the first action is executed.

{% endcut %}

<!-- source: en/_includes/index/troubleshooting.md -->
## Learn more {#troubleshooting}

You can discuss topics of interest in the DivKit user community in Telegram: [https://t.me/divkit_community_en](https://t.me/divkit_community_en).



[DivKit Repository](https://github.com/divkit/divkit)
<!-- endsource: en/_includes/index/troubleshooting.md -->

