---
title: Form repeater
description: Edit an array of records in one form.
---

Use `form.repeater(name, fieldsOrCallback)` for an action input that contains
an array of objects. The schema checks the array key, row field names, and
field value types. Place the returned block inside the form content.

<BacklitExample path="form/repeater" view="create" />

The callback receives a condition composer for one row. A path such as
`isGift` reads that row. It does not read the top-level form.
A lookup field argument inside a repeater must name a field in that row.

## Configuration

Use `peers(...sets)` for fields on one line and `setRoles(map)` for individual
field roles. `setAddAction({ label })` and `setRemoveAction({ label })` set
control text. `setRowTitle(title)` names each row. `setLimits({ min, max })`
sets the row limits in the client. Validate the same limits in the action schema.

Seed rows with `form.withInitialData({ lines: [...] })`. Each row is remapped
through its fields. Defects include an indexed path such as `lines.2.quantity`.
The row count comes from initial data. When no rows are supplied, the client
uses the minimum. A repeater holds one run of fields per row; it does not
accept arbitrary content blocks.

`revealWhen(condition)` controls the complete repeater. It has no enable
condition. Use a field's `enableWhen` to disable that input.
