JEXL Syntax
Basic Syntax
Literals
'text'
123
true
null
[1, 2, 3]
{ id: $context.entity.id, active: true }
Plain JSON objects and arrays are valid JEXL expressions:
{
customerId: $context.form.customerId,
expand: ['CONTACTS', 'ACCOUNTS']
}
Common Data Shapes
Most form expressions work with one of these shapes:
'Postou'
true
['UserRole.Backoffice', 'UserRole.Admin']
{
field: 'code',
operator: 'in',
value: ['SK']
}
{
id: $context.form.customerId,
productSpecId: $context.form.productInternet.productSpecId,
recurring: $context.form.productInternet.recurring
}
Configuration fields often expect an object or array, not only a primitive. For example, a LOV defaultFilters expression usually returns an array of filter objects.
Accessing Data
Use dot access when the property name is known:
$context.form.customerId
$context.form.chars.contractSign.contractSignType
Use array indexing for a known position:
$context.form.productOffer.products[0].productSpecId
Dynamic access such as $context.form[key] is not reliable in every configured field. If you need to work with a known list of possible keys, build an explicit array:
[
{ key: 'productOffer', value: $context.form.productOffer },
{ key: 'productInternet', value: $context.form.productInternet },
{ key: 'productInternetVas', value: $context.form.productInternetVas },
{ key: 'productInternetCpe', value: $context.form.productInternetCpe },
{ key: 'productTv', value: $context.form.productTv },
{ key: 'productTvVas', value: $context.form.productTvVas },
{ key: 'productTvPackage', value: $context.form.productTvPackage },
{ key: 'productTvCpe', value: $context.form.productTvCpe },
{ key: 'productVoice', value: $context.form.productVoice },
{ key: 'productVoiceVas', value: $context.form.productVoiceVas },
{ key: 'productVoiceCpe', value: $context.form.productVoiceCpe },
{ key: 'productMailbox', value: $context.form.productMailbox },
{ key: 'productMax', value: $context.form.productMax },
{ key: 'productEset', value: $context.form.productEset }
].filter(x => x.value != null)
This is the practical replacement for a non-existing keys(...) helper when the set of keys is known.
Comparisons
$context.form.status == 'ACTIVE'
$context.form.amount >= 100
$context.form.type != 'INTERNAL'
Strict comparison such as === and !== can be available, but in configuration expressions it is often more practical to use == / != when inputs can arrive as strings.
Example:
'123' == 123
// true
'123' === 123
// false
Use strict comparison when the type matters. Use normal comparison when the same logical value can arrive as a string or number from different widget/configuration paths.
Logical Operators
$context.form.active && $context.form.amount > 0
$context.form.segment == 'B2B' || $context.form.segment == 'VIP'
!$context.form.disabled
Comments
Some multi-line JEXL fields tolerate JavaScript-style comments:
$context.form.amount > 0
// temporary explanation
/*
longer explanation
*/
$context.form.status == 'ACTIVE'
Use comments sparingly. Many configuration fields are displayed as one-line values, and long comments make the expression harder to read in form configuration.
Fallbacks: ?? And ||
?? uses the fallback only when the left side is null or undefined:
$context.form.count ?? 0
If count is 0, the result remains 0.
|| uses the fallback for any falsy value:
$context.form.label || 'No name'
If label is an empty string, the result will be 'No name'.
Practical rule:
- use
??for numeric fallbacks, so you do not lose0, - use
||for text fallbacks where an empty string means "no value".
Ternary Operator
JEXL expressions do not use classic multi-line if blocks. Use the ternary operator:
$context.form.customerSegment == 'B2B' ? 'Company' : 'Person'
Multiple conditions can be chained, but keep them readable:
$context.form.amount > 1000
? 'HIGH'
: $context.form.amount > 0
? 'LOW'
: 'EMPTY'
If an expression becomes hard to read, move the logic to a helper or backend logic.
Function Calls
Global helper functions are called normally:
dateFormat($context.form.validFrom, 'dd.MM.yyyy')
includesArray($context.form.roles, ['ADMIN', 'SUPPORT'], true)
For arrays and strings, JavaScript-like method syntax is often used:
$context.form.items.map(x => x.name)
$context.form.items.filter(x => x.active)
If you are not sure which form is available in a specific field, test the expression in the JEXL debug console for that form.
Callbacks
Some array operations can use callbacks:
$context.form.items.filter(x => x.quantity > 0)
$context.form.items.map(x => x.name)
There are also helper forms that work with field names:
filter($context.form.items, 'status', 'ACTIVE')
map($context.form.items, 'name')
Arrays, Objects, And Lambdas
A lambda is a small inline function. In:
$context.form.items.map(x => x.name)
x is one item from $context.form.items, and the expression returns its name. The result is an array of names.
In:
$context.form.items.filter(x => x.active)
x => x.active is the condition. Only items where active is truthy stay in the result.
Common method patterns:
$context.form.items.find(x => x.code == 'Internet')
$context.form.items.some(x => x.required)
$context.form.items.every(x => x.status == 'ACTIVE')
The helper form is often easier for simple field checks:
find($context.form.items, 'code', 'Internet')
For characteristic metadata stored as { key, value } objects, filter or find by the key field:
find($context.form.chars.attributes, 'key', 'defaultAttribute').value
Safer form when the key may be missing:
find($context.form.chars.attributes, 'key', 'defaultAttribute')
? find($context.form.chars.attributes, 'key', 'defaultAttribute').value
: null