Portal Community

Minimal Example — Invoice Lines

{
  "id": "invoice-lines",
  "type": "data-table",
  "label": "Invoice Line Items",
  "width": "full",
  "settings": {
    "binding": {
      "source": "$json",
      "path": "invoice.lines"
    },
    "addable": true,
    "deletable": true,
    "columns": [
      { "id": "description", "label": "Description", "type": "text",   "width": "40%" },
      { "id": "qty",         "label": "Qty",          "type": "number", "width": "15%", "settings": { "min": 1, "precision": 0 } },
      { "id": "unit-price",  "label": "Unit Price",   "type": "number", "width": "20%", "settings": { "format": "currency" } },
      { "id": "total",       "label": "Total",        "type": "number", "width": "20%", "settings": { "readOnly": true, "format": "currency" } }
    ]
  }
}

Settings Reference

SettingTypeDefaultDescription
bindingBindingConfigBinding to the array in the form data model
columnsColumn[]Column definitions (see below)
addablebooleanfalseShow Add Row button
deletablebooleanfalseShow Delete button on each row
reorderablebooleanfalseAllow drag-and-drop row reordering
selectablebooleanfalseShow row selection checkboxes (required for deleteSelected action)
addLabelstring"Add Row"Label for the Add Row button
minRowsnumber0Minimum number of rows (prevent deletion below this count)
maxRowsnumberMaximum number of rows (disable Add button when reached)
emptyMessagestring"No items"Message shown when the table has no rows
keyFieldstringColumn id used as the row key for link action navigation

Column Object Schema

interface DataTableColumn {
  id: string;           // Column identifier (also the row property key)
  label: string;        // Column header text
  type: FormControlType; // Input control type rendered in each cell
  width?: string;       // Column width (% or px)
  settings?: object;    // Control-specific settings (same as standalone controls)
  readOnly?: boolean;   // Non-editable column (display only)
  required?: boolean;   // Mark column as required in each row
  sortable?: boolean;   // Allow sorting by this column
  hidden?: boolean;     // Hide column (data still captured)
}

Stored Value Format

The data-table stores its value as an array of row objects in the form data model. Each row object has keys matching the column id values:

// For the invoice-lines table above, stored as:
[
  { "description": "Consulting Services", "qty": 8,  "unit-price": 150,  "total": 1200 },
  { "description": "Travel Expenses",     "qty": 1,  "unit-price": 425,  "total": 425  },
  { "description": "Software License",   "qty": 3,  "unit-price": 99,   "total": 297  }
]

Selectable Rows and deleteSelected Action

When selectable: true, a checkbox appears on each row. Pair this with the deleteSelected action type to allow bulk deletion:

{
  "id": "reminders-table",
  "type": "data-table",
  "settings": {
    "selectable": true,
    "addable": true,
    "deletable": false,
    "columns": [
      { "id": "day",  "label": "Day",  "type": "number" },
      { "id": "note", "label": "Note", "type": "text" }
    ]
  }
}

// Delete selected action in actions[]:
{
  "id": "delete-selected",
  "type": "deleteSelected",
  "label": "Delete Selected",
  "settings": {
    "tableId": "reminders-table"
  }
}

Default Row Values

Pre-populate new rows added via the Add Row button:

{
  "settings": {
    "addable": true,
    "newRowDefaults": {
      "qty": 1,
      "unit-price": 0,
      "vat-rate": 20
    }
  }
}

Row Totals (Read-Only Computed Columns)

Use readOnly: true and a column expression to show computed values. The form engine evaluates the expression using the current row's values:

{
  "id": "line-total",
  "label": "Line Total",
  "type": "number",
  "readOnly": true,
  "settings": {
    "format": "currency",
    "computedValue": "row.qty * row['unit-price']"
  }
}
Data Table + addQuickItems Action The most productive pattern is to pair a data-table with an addQuickItems action. The action adds preset rows to the table with one click — for example, standard service charges or reminder templates. See Data Table Patterns for full examples.