Skip to content

Form Repeat: add and reorder groups of inputs

Reference · Advanced · App Connect

Build a variable-length form with indexed input names and controlled row actions.

Build a variable-length form with indexed input names and controlled row actions.

  • An App Connect page with the matching extension included and a known array of record objects.

Form Repeat clones its child markup into editable rows and rewrites named input/select/textarea fields into an indexed form structure. Use one wrapper per repeated row and give each field its intended base name. It does not insert or update server records until the enclosing form submits.

Give the repeat ID lineItems.

Control or value Meaning and use
ItemsAn array of starting records or a number of blank rows. Bind the inputs to the starting record fields when restoring values. Changing Items or calling Reset rebuilds the rows and can discard current edits.
Min / MaxMinimum and maximum row counts. Runtime defaults are 0 and Infinity. Keep Min <= Max, and use sensible whole numbers. Count checks on the page do not replace server validation.
Sortable / HandleSortable enables the included Sortable library; Handle restricts dragging to a selector within each row. Enable it from initialization if needed: the installed transition from no sortable instance uses an undefined node variable.
AnimationThe sortable animation option. The initial creation path does not pass this option; a later change applies it to an existing instance. Do not assume a nonzero initial value has taken effect.

Add creates a row when under Max. Remove uses Index and respects Min. Move takes Old index/New index; Move to start/end uses an Index. Move before/after moves that row one position, not relative to a separately selected record. Duplicate copies supported field values after the chosen row. Reset rebuilds from configured Items.

Control or value Meaning and use
canAdd / itemscanAdd reports capacity. items exposes child data; it is not automatically the same flat object array that the server receives from named form controls.
$formindex / $indexCurrent zero-based row position. Names are regenerated after moves, for example lineItems[0][title].
$canRemove / move flagsRow-scope flags for disabling actions at minimum count or list boundaries.
Added / Removed / Duplicated / MovedUse these for UI follow-up; count-limit paths can still dispatch a requested-action event. Check actual row count/state for confirmation.
Duplicate boundariesCopies descendant control values, skips passwords/files and does not promise a deep copy of arbitrary custom-component state. Disable Duplicate when canAdd is false; the installed path continues after a blocked Add.

Inside a form, add Form Repeat lineItems with one child wrapper containing an input named title. Set Items 1, Min 1, Max 3. Add a second row, enter Notebook and Pencil, and inspect names lineItems[0][title] and lineItems[1][title]. Move the second row to the start and confirm both values move with their row and indices update. Submit only to a development endpoint prepared to receive that array.

Handle reset and server persistence separately

Section titled “Handle reset and server persistence separately”

Bind field IDs and label-for values so they remain unique per row; repeated static IDs make labels and selectors ambiguous. Removing a row does not delete a stored database record. For editing saved records, carry a separate stable record id and explicitly decide which server rows to insert, update or delete.

Continue with the matching workflow to connect this component to the surrounding page.

You can configure the component, use its exact output shape and verify selection, filtering or local editing with known example records.