Skip to main content

Relation Data Range

Relation data range scripts restrict which target records users can select from a search, multi_search, or foreign_key field.

Use this interaction when the selectable records depend on the source field, current form, row context, current user, or a business rule such as "only active products" or "only customers in the current department".

Configure A Relation Data Range Script​

  1. Open Work > Forms
  2. Open the form that contains the source relation field
  3. Go to Field Design
  4. Select a search, multi_search, or foreign_key field
  5. In the field settings panel, open Relation Data Scope
  6. Select a Studio script and, when needed, a specific script file
  7. Save the field

The script is bound to the source field. Do not configure this rule on the target form's page events.

Script Function​

type RelationDataRangePayload = {
schema: 'soln.runtime-context/v1';
source: {
type: 'relation_data_range';
scope: 'main' | 'child';
fieldApiName: string | null;
targetForm: { id: string; apiName: string; name: string | null };
};
form: { id: string; apiName: string; name: string | null } | null;
record: RuntimeRecord | null;
draft: { data: Record<string, unknown> } | null;
selection: { records: RuntimeRecord[]; childRows: RuntimeChildRow[] };
child: RuntimeChildContext | null;
input: {
search: { keyword: string; batchKeywords: string[]; field: string };
};
result: unknown | null;
runtime: RuntimeMetadata;
};

export default async function main(payload: RelationDataRangePayload) {
return {
ok: true,
effects: [
{
type: 'relationDataFilter',
condition: {
logic: 'and',
children: [
{
field: 'status',
operator: 'eq',
value: 'active',
},
],
},
},
],
};
}

Payload​

FieldTypeDescription
schema'soln.runtime-context/v1'Shared runtime context version
source.type'relation_data_range'Identifies the relation data range source
source.scope'main' | 'child'Whether the source field belongs to the main form or a child table
source.fieldApiNamestring | nullSource relation field API name
source.targetFormRuntimeFormRefTarget form identity
formRuntimeFormRef | nullSource form identity
recordRuntimeRecord | nullCurrent persisted record when available
draft.dataRecord<string, unknown>Current main-form draft values
child.row.dataRecord<string, unknown>Current child-row draft values for child scope
selection.childRowsRuntimeChildRow[]Child rows available to this execution
input.search.keywordstringCurrent search keyword in the selection dialog
input.search.batchKeywordsstring[]Batch search keywords when the selector performs batch lookup
input.search.fieldstringTarget search field used by the selector

Response​

Return a relationDataFilter condition. The condition fields must use target-form field API names, not source-form field names or display labels.

The runtime combines this condition with the user's active selector filter using and.

Effect Response​

return {
ok: true,
effects: [
{
type: 'relationDataFilter',
condition: {
logic: 'and',
children: [
{ field: 'so_product_type', operator: 'eq', value: 'standard' },
],
},
},
],
};

Direct Response​

The runtime also accepts direct forms when the script only needs to return a condition:

return {
relationDataFilter: {
condition: {
logic: 'and',
children: [
{ field: 'so_product_type', operator: 'eq', value: 'standard' },
],
},
},
};
return {
condition: {
logic: 'and',
children: [
{ field: 'so_product_type', operator: 'eq', value: 'standard' },
],
},
};

Example: Active Products Only​

export default async function main(payload) {
if (
payload?.schema !== 'soln.runtime-context/v1' ||
payload?.source?.type !== 'relation_data_range'
) {
return { ok: true };
}

return {
ok: true,
effects: [
{
type: 'relationDataFilter',
condition: {
logic: 'and',
children: [
{
field: 'so_status',
operator: 'eq',
value: 'active',
},
],
},
},
],
};
}

Notes​

  • Bind the script on the source search, multi_search, or foreign_key field
  • Use target-form field API names inside condition.children
  • Use payload.draft.data for main-form values and payload.child.row.data for current child-row values
  • Read selector input from payload.input.search; do not add custom top-level payload properties
  • Do not place this rule on the target form's page-load event