List Formfield
A list field displays a table of rows where each row is created and edited through a dedicated subform pane (drilldown pattern). It supersedes the deprecated table field.
Key features
- Each row is edited in a full-screen subform, giving access to every field type including nested lists.
- The subform is declared as a separate top-level form of type
subformand can be reused across multiple list fields in different forms (e.g. a singleAddresssubform shared by customers, suppliers, orders…). - Supports the same marker properties as the
tablefield (insertMarker,updateMarker,deleteMarker) so playbook idempotency patterns still work. - 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,noOutput,outputObjectandvalueColumndeclared on subform fields are honoured when generating extravars.
Subform declaration
A subform is a top-level form entry with type: subform. It accepts the same fields array as any other form but is never shown in the form tile list and is never submitted directly.
forms:
- 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
| 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 |
| output | |
| output boolean added in version 6.2.0 | Include field value as extravar
Form fields are by default sent as extravars. Note: Default: true |
| noOutput boolean | Do not output as extravar (deprecated)
Deprecated since 6.2.0. Use Default: false |
| 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. 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
forms:
- 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
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)
- 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 produced rows must be objects whose keys match the referenced subform’s field names.
Static default
- 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)
- name: users
type: list
label: Users
subform: User
columns:
- username
- email
expression: fn.fnRestBasic('get','https://api.example.com/users','','my_api_cred','')
refresh: true # add a refresh button (or '30s' for auto-refresh)
From a database query (dbConfig + 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)
- 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
forms:
- 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
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 automatically injects a __parent__ variable into the subform containing a snapshot of all parent form field values (including constants and vars).
Use it with the standard $(...) expression syntax in the subform’s field definitions:
forms:
- name: NodeConfig
type: subform
fields:
- name: node_name
type: text
label: Node name
required: true
- name: node_type
type: enum
values:
- standard
- high-memory
- gpu
# 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
fields:
- name: environment
type: enum
values: [dev, staging, production]
required: true
- name: nodes
type: list
subform: NodeConfig
columns: [node_name, node_type]
__parent__is stripped from Ansible extravars — it is a frontend-only helper. It is never sent to your playbook.