List Formfield
A table of rows, each edited in a subform
A list field displays a table of rows, each created and edited in a dedicated subform pane (a drilldown pattern). It replaces the table field, which was removed in 7.0.0.
Key features
The list field offers the following capabilities:
- Each row is edited in a full-screen subform, giving access to every field type including nested lists.
- The subform is a form of its own, of type
subform, and can be reused across multiple list fields in different forms (e.g. a singleAddresssubform shared by customers, suppliers, orders…). - Marker properties (
insertMarker,updateMarker,deleteMarker) support idempotent playbook patterns. - When
allowDelete: false, pre-existing rows are protected; only rows added in the current session (carrying theinsertMarker) can be deleted. - The
columnsproperty controls which subform fields appear as columns in the summary table. - The output is always an array of objects.
model,output,outputObjectandvalueColumndeclared on subform fields are honored when the extravars are generated.
Subform declaration
A subform is a form of its own with type: subform, in a file of the forms folder like any other form. It accepts the same fields array as any other form, but it never appears in the form tile list and is never submitted directly.
- name: Address
type: subform
fields:
- name: street
type: text
label: Street
required: true
- name: city
type: text
label: City
required: true
- name: country
type: text
label: Country
Properties
The properties available to a list field, grouped by purpose:
| Attribute | Comments |
|---|---|
| basic | |
| name string / required / unique | Field name
This attribute represents the name of the form field. |
| type string / required | Field type
Other attributes might only be available for some field types. Value: list ExamplesText |
| label string | Field label
A friendly name/label for the field. Note: if not set, the field name is used as label, but not when type is html. Since 6.0.3: Supports placeholders for dynamic labels (e.g., |
| help string | Field help message
Some fields require additional help information. This help message will be shown below the field. Since 6.0.3: Supports placeholders for dynamic help text (e.g., |
| subform string / required | Name of the subform that defines one row
For a |
| data | |
| default many | Default value
The type of the value depends on the field type.
For |
| expression string | A javascript expression.
By default this javascript is evaluated on the server side and limited to predefined functions (for security). However in combination with tip : use the alias ExamplesGet a list of users from a rest api Filter and sort an array of objects Make a numbered list Use the alias `local` Use the alias `local_out` |
| runLocal boolean | Run an expression locally
When running expressions, by default they are run remotely on the server. Default: false |
| dbConfig string, array or object | A database connection
When you want to query data from a database, you will need the proper connection information. Examplesget information from a mysql database (legacy example - deprecated) get information from a mysql database (new example) get information from a mysql database (array example) get information from a mongodb |
| query string | The query to select data from a database
This is typically a classic SELECT statement. Examplesget information from a mysql database get information from a mongodb |
| interaction | |
| dependencyFn string added in version 4.0.0 | The dependency logical function
This attribute represents the logical function between multiple dependencies. Choices:
|
| dependencies list / elements=object | Show/hide this field based on the values or other fields
Each dependency element is either an object with the following 2 attributes:
Or with the following 2 attributes:
Use in combination with attribute ExamplesShow a field based on a checkbox Show a field if another field is valid Show a field based on 2 fields, using the 'or' function |
| allowInsert boolean | Allow table/list insert
A table or list can be used to modify existing data. If new data is not allowed, set this property to false. Default: true |
| allowDelete boolean | Allow table/list delete
A table can be used to modify existing data. If you don’t was recoreds to be deleted, set this property to false. Default: true |
| showLoadButton boolean added in version 6.1.5 | Show load button for file import
Enables a “Load YAML” button that allows users to import data from .yml or .yaml files. For list fields, the YAML file must contain a valid array of objects. For yaml fields, the file can contain any valid YAML structure. Single objects are automatically wrapped in arrays for list fields. Default: false ExamplesList with YAML import YAML field with file import |
| showDownloadButton boolean added in version 6.1.5 | Show download button for file export
Enables a “Download” button that exports the field content as a .yml file. The filename is automatically generated from the field name. Default: false |
| output | |
| output boolean added in version 6.2.0 | Include field value as extravar
Form fields are by default sent as extravars. Default: true |
| model string or array | Extravar modelling
By default, a field is sent as a root-extravar. ExamplesModel 2 fields together as a single object |
| deleteMarker string | Adds an additional deletemarker field
When you remove a record in a table, it gets removed. Since 6.4.1 the markers of a ExamplesMark delete record |
| insertMarker string | Adds an additional insertmarker field
When you add a record in a table, it simply gets added. ExamplesMark new record |
| updateMarker string added in version 5.1.0 | Adds an additional updatemarker field
In addition to the insert and delete markers, you can also add an update marker. ExamplesMark updated record |
| security | |
| noLog boolean added in version 2.2.3 | Disable backend logging
Disables logging in the backend, to hide passwords for example. Default: false Exampleshide password in log |
| validation | |
| required boolean | Required field
Makes the field required. Default: false |
| validIf object added in version 2.2.4 | An field based validation (field must be true)
Enforces a validation where a referencing (expression) field must be true. This field requires an object with 2 attributes:
ExamplesIp must be pingable |
| validIfNot object added in version 2.2.4 | An field based validation (field must be false)
Enforces a validation where a referencing (expression) field must be false. This field requires an object with 2 attributes:
ExamplesCheck if powered off |
| ignoreIncomplete boolean | Allow form submit on non-evaluated placeholders
When an expression-based field has placeholders, Default: false |
| visualization | |
| group string | The field group name
With this attribute you can group fields together. |
| line string added in version 4.0.3 | The field line name
With this attribute you can group fields in a single line together. |
| width string added in version 4.0.3 | The field width
With this attribute you can set the width of a field. Choices:
ExamplesName and lastname |
| titleAdd string | Title shown in the subform pane when adding a new row
When you add a row through a |
| titleEdit string | Title shown in the subform pane when editing an existing row
When you edit a row through a |
| columns array | The list of columns visible in the dropdown/table
For an ExamplesShow only wanted columns |
Examples
Shared address subform
One Address subform reused by two list fields of the same form:
- name: Address
type: subform
fields:
- name: street
type: text
label: Street
required: true
- name: city
type: text
label: City
required: true
- name: country
type: text
label: Country
- name: Create customer
type: ansible
playbook: customer.yaml
roles: [public]
fields:
- name: name
type: text
label: Customer name
required: true
- name: addresses
type: list
label: Addresses
subform: Address
columns:
- city
- country
titleAdd: Add address
titleEdit: Edit address
allowInsert: true
allowDelete: true
Marker tracking (idempotency-aware)
Preloaded rows are protected, and the markers tell the playbook which rows are new, changed or removed:
- name: people
type: list
label: People
subform: Person
allowDelete: false # preloaded rows are protected
insertMarker: added # session-added rows remain removable
updateMarker: updated
deleteMarker: removed
columns:
- name
- email
Pre-populating rows
A list can be pre-filled from three sources. In every case, the resulting rows must be objects whose keys match the field names of the referenced subform.
Static default
Rows written in the form itself:
- name: addresses
type: list
label: Addresses
subform: Address
columns:
- city
- country
default:
- street: Main 1
city: Brussels
country: BE
- street: Side 22
city: Paris
country: FR
From a REST API (expression)
Rows loaded from a REST API by a server-side expression:
- name: users
type: list
label: Users
subform: User
columns:
- username
- email
expression: fn.fnRestBasic('get','https://api.example.com/users','','my_api_cred','')
From a database query (dbConfig + query)
Rows loaded from a database query:
- name: servers
type: list
label: Servers
subform: Server
columns:
- hostname
- role
dbConfig: CMDB_CONN
query: SELECT hostname, role FROM servers WHERE active = 1
From a local expression (runLocal)
Rows computed in the browser by a local expression:
- name: ports
type: list
label: Open ports
subform: Port
columns:
- port
- protocol
runLocal: true
expression: |
[
{ port: 22, protocol: 'tcp' },
{ port: 80, protocol: 'tcp' },
{ port: 443, protocol: 'tcp' }
]
Nested lists
A subform can hold a list field of its own, for a list inside each row:
- name: Address
type: subform
fields:
- name: street
type: text
label: Street
- name: city
type: text
label: City
- name: Person
type: subform
fields:
- name: name
type: text
label: Name
required: true
- name: addresses
type: list
label: Addresses
subform: Address
columns:
- street
- city
- name: My Form
type: ansible
playbook: people.yaml
roles: [public]
fields:
- name: people
type: list
label: People
subform: Person
columns:
- name
- addresses
Accessing parent form data via __parent__
When a subform row editor opens, AnsibleForms injects a __parent__ variable into the subform. It holds a snapshot of all parent form field values, including constants and vars.
Reference it with the standard $(...) expression syntax in the field definitions of the subform:
- name: NodeConfig
type: subform
fields:
- name: node_name
type: text
label: Node name
required: true
- name: node_type
type: enum
# only offer gpu in production environments (parent field)
expression: |
'$(__parent__.environment)' === 'production'
? ['standard', 'high-memory', 'gpu']
: ['standard', 'high-memory']
runLocal: true
default: __auto__
- name: Deploy cluster
type: ansible
playbook: deploy.yml
roles: [public]
fields:
- name: environment
type: enum
values: [dev, staging, production]
required: true
- name: nodes
type: list
subform: NodeConfig
columns: [node_name, node_type]
__parent__is a frontend-only helper. It is stripped from the Ansible extravars and never sent to the playbook.