mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-02-23 14:39:32 +08:00
163 lines
7.3 KiB
YAML
163 lines
7.3 KiB
YAML
_ref:
|
|
path: templates/general.yaml.njk
|
|
vars:
|
|
pageId: lists
|
|
pageTitle: Lists
|
|
section: Concepts
|
|
filePath: concepts/lists.yaml
|
|
content:
|
|
- id: md1
|
|
type: MarkdownWithCode
|
|
properties:
|
|
content: |
|
|
List category blocks render multiple [`content areas`](/layout), based on data in the [`state`](/context-and-state) object.
|
|
|
|
Since the content area might contain input blocks, the block has an array value in state, with it's `block id` as key. For each item in the array, an content area (or set of content areas is rendered). Multiple list blocks can be nested.
|
|
|
|
### List indices and block ids
|
|
|
|
If a block is to be rendered in an list's content area, the block id should contain a list index placeholder (specified with the `$` symbol) for each list it is a part of. These placeholders will be populated with the blocks `list indices`. The `list indices` are a array of integers, indicating at which position in the list the block is, for each level of list blocks (zero indexed). The block id should be in valid dot-notation once the placeholders have been substituted.
|
|
|
|
This can be made more clear with a example. Suppose we have a list block with id `contacts`. Inside this list we have a text input block for the contact name. We would like our state to look like:
|
|
```yaml
|
|
contacts:
|
|
- name: Name 1
|
|
- name: Name 2
|
|
```
|
|
|
|
The id for the text input block should be `contacts.$.name`. Each text input block will be given an indexed id based on it's position in the contacts list (`contacts.0.name`, `contacts.1.name`, etc.).
|
|
|
|
Suppose we also want to add a emails array for each contact. To do this, we can add another list block in the `contacts` array, and add a text input inside the emails array. If we want the emails to be a array of strings, i.e. our `state` should look like:
|
|
|
|
```yaml
|
|
contacts:
|
|
- name: Name 1
|
|
emails:
|
|
- email1@example.com
|
|
- email2@example.com
|
|
- name: Name 2
|
|
emails: []
|
|
```
|
|
|
|
our config should look like:
|
|
```yaml
|
|
id: contacts
|
|
type: ControlledList
|
|
properties:
|
|
# ...
|
|
blocks:
|
|
- id: contacts.$.name
|
|
type: TextInput
|
|
properties:
|
|
# ...
|
|
- id: contacts.$.emails
|
|
type: ControlledList
|
|
properties:
|
|
# ...
|
|
blocks:
|
|
- id: contacts.$.emails.$
|
|
type: TextInput
|
|
properties:
|
|
# ...
|
|
```
|
|
|
|
Note that the id of the emails list block is `contacts.$.emails` and that it has one `$` placeholder since it is inside the `contacts` list, and the id of the email text input is `contacts.$.emails.$`, which has two `$` placeholders since it is in both the `contacts` and `contacts.$.emails` lists.
|
|
|
|
The ids of the `contacts.$.emails.$` text input blocks will look like `contacts.0.emails.3` or `contacts.2.emails.1`, and this will result in the `state` where the emails on a contact are an array of strings.
|
|
|
|
### List indices in operators
|
|
|
|
List indices are also supported in "getter" operators like `_state`. If the operator is given a key that contains `$` placeholders, and the operator is called from a block with list indices, the placeholders will be populated with the blocks list indices. These indices are populated on `actions` called by the block, and are even populated in `connections` and `requests` if the block that triggered the `Request` action has list indices. This can be used to get values from the `state` array the block is a part of, or even values from another array at the same index.
|
|
|
|
### List block methods
|
|
|
|
List blocks can provide methods to change their values. These are
|
|
|
|
#### `pushItem`
|
|
Add an item at the end of the list.
|
|
|
|
#### `unshiftItem`
|
|
Add an item at the start of the list.
|
|
|
|
#### `removeItem`
|
|
Remove an item at the specified index.
|
|
|
|
#### `moveItemDown`
|
|
Move the item at the specified index one position to the start of the list. If the item is at the start if the list, the item remains at position `0`.
|
|
|
|
#### `moveItemUp`
|
|
Move the item at the specified index one position to the end of the list. If the item is at the end if the list, the item remains at it's position.
|
|
|
|
#### Example
|
|
```yaml
|
|
id: page
|
|
type: PageHeaderMenu
|
|
blocks:
|
|
- id: add_item_at_start
|
|
type: Button
|
|
events:
|
|
onClick:
|
|
- id: add_item_at_start
|
|
type: CallMethod
|
|
params:
|
|
blockId: list
|
|
method: unshiftItem
|
|
- id: add_item_at_end
|
|
type: Button
|
|
events:
|
|
onClick:
|
|
- id: add_item_at_end
|
|
type: CallMethod
|
|
params:
|
|
blockId: list
|
|
method: pushItem
|
|
- id: list
|
|
type: List
|
|
blocks:
|
|
- id: list.$.move_item_down
|
|
type: Button
|
|
events:
|
|
onClick:
|
|
- id: move_item_down
|
|
type: CallMethod
|
|
params:
|
|
blockId: list
|
|
method: moveItemDown
|
|
args:
|
|
- _index: 0 # Get the first index in the indices array
|
|
- id: list.$.move_item_up
|
|
type: Button
|
|
events:
|
|
onClick:
|
|
- id: move_item_up
|
|
type: CallMethod
|
|
params:
|
|
blockId: list
|
|
method: moveItemUp
|
|
args:
|
|
- _index: 0
|
|
- id: list.$.remove_item
|
|
type: Button
|
|
events:
|
|
onClick:
|
|
- id: remove_item
|
|
type: CallMethod
|
|
params:
|
|
blockId: list
|
|
method: removeItem
|
|
args:
|
|
- _index: 0
|
|
```
|
|
|
|
### Lists and state
|
|
|
|
List blocks create a content area for each item in `state`. If `state` is updated, the list block will also update, creating or destroying content areas as necessary. Thus list blocks can also be manipulated by setting `state` directly using the [`SetState`](/SetState) operator.
|
|
|
|
- _ref:
|
|
path: templates/navigation_buttons.yaml
|
|
vars:
|
|
previous_page_title: Secrets
|
|
previous_page_id: secrets
|
|
next_page_title: Hosting Files
|
|
next_page_id: hosting-files
|