Maintained reference:
customeditabletableis the up-to-date version of this topic. This page keeps older notes and examples.
The Custom Editable Table Widget is a tabular component for collecting and editing structured data in rows and columns within a form.
This widget enables users to input, edit, and validate tabular data with support for multiple input types (text, number, email, date, select) in a structured table format. It provides real-time validation, custom column configurations, and optional row management (add/delete). The component integrates seamlessly with Formly forms and returns data in a structured format.
{
"key": "productDetails",
"type": "customeditabletable",
"props": {
"label": "Product Details",
"rowColumnTitle": "Product Name",
"showRowLabels": true,
"rows": [
{
"key": "row1",
"label": "Product A",
"disabled": false
},
{
"key": "row2",
"label": "Product B",
"disabled": false
}
],
"columns": [
{
"key": "quantity",
"label": "Quantity",
"type": "number",
"required": true,
"min": 0,
"max": 1000,
"placeholder": "Enter quantity",
"disabled": false,
"width": "150px"
},
{
"key": "price",
"label": "Price (RWF)",
"type": "number",
"required": true,
"min": 0,
"placeholder": "Enter price",
"disabled": false
},
{
"key": "status",
"label": "Status",
"type": "select",
"required": true,
"options": [
{ "label": "Available", "value": "available" },
{ "label": "Out of Stock", "value": "out_of_stock" },
{ "label": "Discontinued", "value": "discontinued" }
],
"placeholder": "Select status",
"disabled": false
},
{
"key": "notes",
"label": "Notes",
"type": "text",
"required": false,
"placeholder": "Additional notes",
"pattern": "^[a-zA-Z0-9\\s]*$"
}
],
"allowRowAddition": false,
"allowRowDeletion": false,
"disabled": false,
"customTableClass": ""
},
"validation": {
"messages": {
"required": "This field is required"
}
}
}
The component returns data in the following format:
{
"row1": {
"quantity": 100,
"price": 5000,
"status": "available",
"notes": "Stock ready"
},
"row2": {
"quantity": 50,
"price": 7500,
"status": "out_of_stock",
"notes": ""
}
}
Below is a full service configuration of how the component can be used:
[
{
"type": "sections",
"props": {},
"fieldGroup": [
{
"key": "editableTableExamples",
"type": "formly-group",
"props": {
"label": "Editable Table Examples"
},
"fieldGroup": [
{
"key": "basicInventory",
"type": "block",
"props": {
"label": "Basic Inventory Example"
},
"fieldGroup": [
{
"key": "inventory",
"type": "customeditabletable",
"props": {
"label": "Product Inventory",
"rowColumnTitle": "Product",
"showRowLabels": true,
"rows": [
{ "key": "product1", "label": "Laptop" },
{ "key": "product2", "label": "Mouse" }
],
"columns": [
{
"key": "quantity",
"label": "Quantity",
"type": "number",
"required": true,
"min": 0
},
{
"key": "price",
"label": "Price (RWF)",
"type": "number",
"required": true,
"min": 0
}
]
}
}
]
},
{
"key": "employeeInfo",
"type": "block",
"props": {
"label": "Employee Information Example"
},
"fieldGroup": [
{
"key": "employees",
"type": "customeditabletable",
"props": {
"label": "Employee Contact Information",
"rowColumnTitle": "Employee",
"showRowLabels": true,
"rows": [
{ "key": "emp1", "label": "John Doe" },
{ "key": "emp2", "label": "Jane Smith" }
],
"columns": [
{
"key": "email",
"label": "Email",
"type": "email",
"required": true
},
{
"key": "department",
"label": "Department",
"type": "select",
"required": true,
"options": [
{ "label": "IT", "value": "it" },
{ "label": "HR", "value": "hr" }
]
}
]
}
}
]
}
]
}
]
}
]
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
label |
string | No | - | Label displayed above the table |
rowColumnTitle |
string | No | "" | Title for the row labels column header |
showRowLabels |
boolean | No | false | Whether to display row labels column |
rows |
array | Yes | [] | Array of row configurations |
columns |
array | Yes | [] | Array of column configurations |
allowRowAddition |
boolean | No | false | Enable "Add Row" functionality |
allowRowDeletion |
boolean | No | false | Enable row deletion buttons |
disabled |
boolean | No | false | Disable all inputs in the table |
customTableClass |
string | No | "" | Custom CSS class for the table |
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
key |
string | Yes | - | Unique identifier for the row |
label |
string | Yes | - | Display label for the row |
disabled |
boolean | No | false | Disable all inputs in this row |
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
key |
string | Yes | - | Unique identifier for the column (field name) |
label |
string | Yes | - | Display label for the column header |
type |
string | No | "text" | Input type: "text", "number", "email", "date", "select" |
required |
boolean | No | false | Whether the field is required |
disabled |
boolean | No | false | Disable all inputs in this column |
placeholder |
string | No | "" | Placeholder text for the input |
width |
string | No | - | CSS width for the column (e.g., "150px", "20%") |
min |
number | No | - | Minimum value (for number type) |
max |
number | No | - | Maximum value (for number type) |
pattern |
string | No | - | Regex pattern for validation (for text type) |
options |
array | No | [] | Options for select type: [{label: string, value: any}] |
type: "text")pattern validationrequired validationtype: "number")min and max validationrequired validationtype: "email")required validationtype: "date")required validationtype: "select")irembogov-select componentoptions array with label and value propertiesrequired validation| Validation | Type | Description | Usage |
|---|---|---|---|
required |
boolean | Marks field as required | Set required: true in column config |
min |
number | Minimum value for numbers | Set min: value in column config (number type only) |
max |
number | Maximum value for numbers | Set max: value in column config (number type only) |
pattern |
string | Regex pattern validation | Set pattern: "regex" in column config (text type only) |
Custom validation messages can be configured in the validation.messages object:
{
"validation": {
"messages": {
"required": "This field is required",
"min": "Value must be at least {min}",
"max": "Value cannot exceed {max}",
"pattern": "Invalid format"
}
}
}