Skip to content

PrimeRepeater ​

A FormKit component for repeating groups of inputs with add, remove, clone, and reorder functionality.

Live Example on Website

Usage ​

vue
<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 ​

vue
<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 ​

NameTypeDefaultDescription
newItemobject{}Template object for new items
insertButtonLabelstring'Add Item'Label for the insert button
insertButtonClassstring''CSS class for insert button
insertButtonSizestring''Size of insert button (small, large)
alwaysDisplayInsertButtonbooleanfalseAlways show insert button
listClassstring''CSS class for the list container
listItemClassstring''CSS class for each list item
groupClassstring''CSS class for the input group
hideButtonGroupbooleanfalseHide all action buttons
hideMoveButtonsbooleanfalseHide move up/down buttons
buttonGroupClassstring''CSS class for button group
buttonGroupItemClassstring''CSS class for each button
buttonSizestring''Size of action buttons
displayCloneButtonbooleanfalseShow clone button
displayAddButtonbooleanfalseShow add button
displayDeleteButtonbooleantrueShow delete button
draggablebooleanfalseEnable drag-and-drop reordering
displayDragHandlebooleanfalseShow drag handle
dragHandleClassstring''Extra CSS class for the drag handle
dragHandleIconClassstring'pi pi-bars'Icon class used inside the drag handle
moveUpLabelstring'Move item up'Accessible name and tooltip of the move up button
moveDownLabelstring'Move item down'Accessible name and tooltip of the move down button
deleteLabelstring'Delete item'Accessible name and tooltip of the delete button
cloneLabelstring'Clone item'Accessible name and tooltip of the clone button
addLabelstring'Add item below'Accessible name and tooltip of the add button
undoDeletebooleanfalseOffer to put back the row that was deleted last
undoLabelstring'Undo'Label of the undo button
deletedLabelstring'Item deleted'Message that is shown with the undo button
undoTimeoutnumber8000Milliseconds 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:

ts
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.

ts
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 draggable is enabled
  • Customizable: Full control over styling and button visibility

Example with Custom Styling ​

vue
<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>

FormKit PrimeVue Module