Working with Data Grids
Datagrid is a repeating row component. The submitter can add as many rows as they need, each containing the same set of columns. Use it for expense line items, asset request lists, attendee lists, delegation lists — any situation where you need a variable number of similar entries.
Data Shape
Datagrid stores as an array of objects. Each row is one object; each column is a key in that object.
[
{ "itemName": "Laptop", "quantity": 2, "unitPrice": 4500 },
{ "itemName": "Monitor", "quantity": 1, "unitPrice": 1200 }
]
This is a different shape from flat form fields. Flag it to your workflow designer and document template author upfront — they need to loop through the array, not read a single value.
Display Tab Settings
Open the Datagrid settings → Display tab.
Add Another Text Changes the label on the Add Row button. The default is "Add Another". Change it to something meaningful — "Add Item", "Add Employee", "Add Expense".
Disable Adding / Removing Rows Hides the Add and Remove buttons entirely. Use this when the number of rows is fixed at design time — for example, a checklist the builder pre-populates. The submitter can fill in the rows but cannot change how many there are.
Initialize Empty When ticked, the Datagrid loads with zero rows. The submitter must add the first row manually. Use this when filling in the Datagrid is optional — the submitter may have nothing to add. The default is one empty row on load.
Validation Tab Settings
Open the Datagrid settings → Validation tab.
Maximum Length Sets the maximum number of rows. The Add Row button disappears once this limit is reached — submitters do not see an error message, the button simply stops appearing. If you set a max, add a description on the Datagrid label so submitters know why the button is gone.
Custom Validation JS — minimum rows To require at least one row, use Custom Validation JS on the Datagrid itself:
valid = (value.length >= 1) ? true : 'At least one item is required.';
Calculated Columns
Calculated values work inside Datagrid rows. The variable context inside a row is different from the rest of the form.
| Variable | What it gives you |
|---|---|
row.fieldKey | Another field in the same row |
rowIndex | The current row number (0-based) |
data.fieldKey | Any field on the whole form |
To add a calculated column:
- Add a Number component inside the Datagrid
- Open its Data tab → scroll to Calculated Value
- Enter an expression using
row.fieldKey
Line total example:
value = (row.quantity && row.unitPrice) ? row.quantity * row.unitPrice : 0;
Set the calculated column to Disabled in the Display tab so submitters cannot overwrite it.
Inside a Datagrid row, data.quantity refers to a field named quantity on the whole form, not the column in this row. Use row.quantity to read a column in the same row.
Unique validation is not reliable on fields inside a Datagrid. Do not tick Unique on any Datagrid column.
Advanced Patterns
Row number column
Add a disabled Number or Text Field inside the Datagrid:
value = rowIndex + 1;
Grand total outside the Datagrid
Add a calculated Number field below the Datagrid:
value = (data.items || []).reduce(function (sum, row) {
return sum + ((row.quantity || 0) * (row.unitPrice || 0));
}, 0);
Count rows
value = (data.items || []).length;
Count rows matching a condition
value = (data.items || []).filter(function (row) {
return row.status === 'Rejected';
}).length;
Summary text (for emails, documents, approval views)
value = (data.items || []).map(function (row, index) {
return (index + 1) + '. ' + row.itemName + ' x ' + row.quantity;
}).join('\n');
Prevent duplicate values
Because Unique is not reliable inside Datagrid, validate duplicates on the Datagrid itself using Custom Validation JS:
var names = (value || []).map(function (row) { return row.itemName; }).filter(Boolean);
valid = names.length === new Set(names).size
? true
: 'Duplicate item names are not allowed.';
Reference the previous row
value = rowIndex > 0 ? data.items[rowIndex - 1].balance : 0;
Use this carefully — data.items[rowIndex - 1] does not exist for the first row.
OSPROV-Specific Behaviours
Excel paste When a submitter copies a block of cells from Excel and presses Ctrl+V in the first text input of a Datagrid row, OSPROV fills the entire grid automatically — tabs separate columns, newlines separate rows. Column order must match the Datagrid column order. This is a submitter feature you do not configure — train submitters on it for large data entry tasks.
MasterData Select inside Datagrid URL-based Select fields (MasterData) work inside Datagrid rows. Linked submission icons appear in the submission view just as they do at form level.
Label resolution OSPROV automatically resolves Select and Radio values to their labels when displaying Datagrid rows in submissions. What you see in the submission view may differ from the raw stored value.