List category blocks render multiple content areas
, based on data in the 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:
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:
contacts:
- name: Name 1
emails:
- email1@example.com
- email2@example.com
- name: Name 2
emails: []
our config should look like:
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
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
operator.