PrimeRepeater
A FormKit component for repeating groups of inputs with add, remove, clone, and reorder functionality.
Usage
<FormKit
type="primeRepeater"
name="items"
:newItem="{ name: '', value: '' }"
>
<FormKit type="primeInputText" name="name" label="Name" />
<FormKit type="primeInputText" name="value" label="Value" />
</FormKit>Object-based Example
<script setup>
const schema = [
{
$formkit: 'primeRepeater',
name: 'attacks',
label: 'Attacks List',
help: 'Add, clone, move, and delete attacks using the buttons',
listItemClass: 'flex gap-2',
groupClass: 'grid grid-cols-8 gap-4',
buttonGroupClass: 'mt-6 flex gap-1',
displayCloneButton: true,
displayAddButton: true,
displayDeleteButton: true,
insertButtonLabel: 'Add Attack',
alwaysDisplayInsertButton: true,
newItem: { name: '', damage: '' },
children: [
{
$formkit: 'primeInputText',
label: 'Name',
name: 'name',
outerClass: 'col-span-5',
},
{
$formkit: 'primeInputText',
label: 'Damage',
name: 'damage',
outerClass: 'col-span-3',
},
],
},
]
const data = {
attacks: [
{ name: 'Sword', damage: '2D6' },
{ name: 'Dagger', damage: '1D6' },
],
}
</script>
<template>
<FormKit :schema="schema" :data="data" />
</template>Props
| Name | Type | Default | Description |
|---|---|---|---|
| newItem | object | {} | Template object for new items |
| insertButtonLabel | string | 'Add Item' | Label for the insert button |
| insertButtonClass | string | '' | CSS class for insert button |
| insertButtonSize | string | '' | Size of insert button (small, large) |
| alwaysDisplayInsertButton | boolean | false | Always show insert button |
| listClass | string | '' | CSS class for the list container |
| listItemClass | string | '' | CSS class for each list item |
| groupClass | string | '' | CSS class for the input group |
| hideButtonGroup | boolean | false | Hide all action buttons |
| hideMoveButtons | boolean | false | Hide move up/down buttons |
| buttonGroupClass | string | '' | CSS class for button group |
| buttonGroupItemClass | string | '' | CSS class for each button |
| buttonSize | string | '' | Size of action buttons |
| displayCloneButton | boolean | false | Show clone button |
| displayAddButton | boolean | false | Show add button |
| displayDeleteButton | boolean | true | Show delete button |
| draggable | boolean | false | Enable drag-and-drop reordering |
| displayDragHandle | boolean | false | Show drag handle |
| dragHandleClass | string | '' | Extra CSS class for the drag handle |
| dragHandleIconClass | string | 'pi pi-bars' | Icon class used inside the drag handle |
| moveUpLabel | string | 'Move item up' | Accessible name and tooltip of the move up button |
| moveDownLabel | string | 'Move item down' | Accessible name and tooltip of the move down button |
| deleteLabel | string | 'Delete item' | Accessible name and tooltip of the delete button |
| cloneLabel | string | 'Clone item' | Accessible name and tooltip of the clone button |
| addLabel | string | 'Add item below' | Accessible name and tooltip of the add button |
| undoDelete | boolean | false | Offer to put back the row that was deleted last |
| undoLabel | string | 'Undo' | Label of the undo button |
| deletedLabel | string | 'Item deleted' | Message that is shown with the undo button |
| undoTimeout | number | 8000 | Milliseconds the undo is offered, 0 keeps it until another row is deleted |
Accessible button names
The row buttons only show an icon. Each one has an accessible name and a tooltip made of its label and the number of its row, for example Delete item 2, so the buttons of different rows can be told apart. Set the label props to change the text, for example to translate it:
const attacks = {
$formkit: 'primeRepeater',
name: 'attacks',
deleteLabel: 'Eintrag löschen', // `Eintrag löschen 2`
moveUpLabel: 'Eintrag nach oben',
moveDownLabel: 'Eintrag nach unten',
cloneLabel: 'Eintrag duplizieren',
addLabel: 'Eintrag darunter einfügen',
}Undo of a delete
A row that is deleted is gone at once. Set undoDelete and the repeater shows the message Item deleted with an Undo button for a few seconds. Undo puts the row back at the place it had, and only the row that was deleted last can be put back. The bar is part of the repeater and needs no toast or dialog service, and it is announced to screen readers.
const attacks = {
$formkit: 'primeRepeater',
name: 'attacks',
undoDelete: true,
undoTimeout: 5000, // the undo is offered for 5 seconds
deletedLabel: 'Eintrag gelöscht',
undoLabel: 'Rückgängig',
}The row is not put back when the list already has maxItems rows.
Features
- Add Items: Insert new items at the beginning or after existing items
- Remove Items: Delete items from the list
- Clone Items: Duplicate existing items
- Reorder Items: Move items up or down in the list
- Drag and Drop: Reorder items by dragging list rows when
draggableis enabled - Customizable: Full control over styling and button visibility
Example with Custom Styling
<FormKit
type="primeRepeater"
name="inventory"
insertButtonLabel="Add Item"
listItemClass="flex gap-2 mb-2"
groupClass="grid grid-cols-12 gap-4"
buttonGroupClass="flex gap-1"
:displayCloneButton="false"
:displayAddButton="false"
:alwaysDisplayInsertButton="true"
:newItem="{ item: '', quantity: 1 }"
>
<FormKit type="primeInputText" name="item" label="Item" outerClass="col-span-8" />
<FormKit type="primeInputNumber" name="quantity" label="Qty" outerClass="col-span-4" />
</FormKit>