Field array form

SvForm field array (type: array): a repeatable group with add / remove rows, per-row validation (each item validates against itself), required / minItems gating, and an array value in the submitted payload - an invoice line-items form.

A live, editable Svelte 5 component example from the SvGrid gallery (Layout). Read the SvGrid UI component docs for the full API.

About this example

A field array in SvForm for Svelte 5: type 'array' with itemFields renders a repeatable group with add and remove rows, each row validating against its own values so within-row rules work, required and minItems gating the count, and an array of item objects in the submitted payload. The demo is an invoice line-items form.

SvForm FIELD ARRAY: a repeatable group. type: 'array' + itemFields renders add/remove rows; each row's fields validate against that row (so within-row rules work), and required / minItems gate the count. The value is an array of item objects, included in the submitted payload.

Imports, features and API used

Imports: @svgrid/grid

Frequently asked questions

How do I declare a repeatable group?

Add a field with type: 'array' and itemFields listing the fields of one row. The form renders the rows from the initial array with add and remove buttons.

How does per-row validation work?

Each row's validate functions receive that row's values, so a rule such as quantity greater than zero applies within the row, and errors show on the row's field.

How do I require at least one row?

Set minItems on the array field, or required for at least one; the form blocks submit and shows a message until the count is met.

Related documentation

Related articles

Source code (325-form-array.svelte)

<script lang="ts">
  /**
   * SvForm FIELD ARRAY: a repeatable group. `type: 'array'` + `itemFields` renders
   * add/remove rows; each row's fields validate against that row (so within-row
   * rules work), and `required` / `minItems` gate the count. The value is an array
   * of item objects, included in the submitted payload.
   */
  import { SvForm, rules } from '@svgrid/grid'
  import type { FormEntry } from '@svgrid/grid'

  const schema: FormEntry[] = [
    { name: 'client', label: 'Bill to', required: true, full: true },
    { name: 'items', label: 'Line items', type: 'array', required: true, minItems: 1, addLabel: '+ Add line', itemFields: [
      { name: 'desc', label: 'Description', required: true },
      { name: 'qty', label: 'Qty', type: 'number', required: true, rules: [rules.min(1)] },
      { name: 'price', label: 'Unit price', type: 'number', required: true, rules: [rules.min(0)] },
    ] },
  ]

  let result = $state<string>('')
</script>

<div class="wrap">
  <header>
    <h2>Field array</h2>
    <p>
      A repeatable group: add and remove line items, each validated per row (try
      submitting with an empty description or qty 0). The value is an array of item
      objects - submit to see the payload.
    </p>
  </header>

  <div class="card">
    <SvForm
      fields={schema}
      submitLabel="Create invoice"
      initial={{ client: '', items: [{ desc: '', qty: 1, price: 0 }] }}
      onSubmit={(v) => { result = JSON.stringify(v, null, 2) }}
    />
  </div>

  {#if result}
    <pre class="result">{result}</pre>
  {/if}
</div>

<style>
  .wrap { padding: 20px; max-width: 680px; display: flex; flex-direction: column; gap: 16px; }
  header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
  header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; line-height: 1.5; }
  .card { padding: 20px; border: 1px solid var(--sg-border, #e2e8f0); border-radius: 12px; }
  .result { margin: 0; padding: 14px; background: var(--sg-header-bg, #f8fafc); border: 1px solid var(--sg-border, #e2e8f0); border-radius: 10px; font-size: 12px; overflow: auto; }
</style>

View this example on GitHub

More Layout examples

  • Account & security settings console - A real SaaS settings surface composed from the UI kit: SvMenubar app bar, promise + Undo-action toasts on save, SvPopconfirm on destructive rows, SvHoverCard teammate previews, and frame input adornments (leading icons, prefix affixes, masked API key). Profile / Team / Security tabs over SvCard + SvStat.
  • Invoice builder - An adornment-heavy money form: currency prefixes, % suffixes, masked tax IDs (frame adornments), line items with SvPopconfirm delete + Undo action toasts, live SvStat totals, an SvHoverCard tax hint, and a promise toast on Send. Pure UI-kit composition.
  • Operations KPI dashboard - A KPI console: SvStat + SvSparkline tiles, an SvGauge SLA dial, SvHoverCard drill-down previews per service, an SvMenubar toolbar (View / Range / Actions) and a promise toast on Refresh. Pure UI-kit composition, no grid dependency.
  • Form: rich field types - SvForm reaching the whole input suite from one schema - phone, country, mask, combobox, radio, slider, tags, datetime and file - plus per-field help text, a readonly field, column span, and a promise toast on submit.
  • Form: cascading fields - SvForm dependent selects - a child list derives from the parent value via a function `options`, and `dependsOn` clears the child when the parent changes so a stale selection never lingers. Country -> State -> City.