Formula Reference¶
Useful formula patterns for Versaa form calculated fields, visibility conditions, and value formulas. All formulas run as single-line JavaScript expressions.
General Rules¶
- All Versaa formulas must be single-line JavaScript expressions — no
const,let,var, or multi-line blocks. - Reference form items via
$formItem.FieldName. - Formulas that chain through two or more reactive dependencies may not re-evaluate correctly — calculate directly where possible.
- When prompting an LLM for formula help, specify: "as a one-liner, minimal abstraction, no const declarations".
Null Coalescing / Default Values¶
// Use empty string if field is null or empty
($formItem.FieldName || "")
// Use 0 if field is null or empty
($formItem.FieldName || 0)
// Conditional with fallback
($formItem.SomeField ? $formItem.SomeField : "Default Text")
Concatenation¶
// Simple string join
$formItem.FirstName + " " + $formItem.LastName
// With null safety
($formItem.FirstName || "") + " " + ($formItem.LastName || "")
// Multi-field concatenation
$formItem.AddressLine1 + ", " + $formItem.AddressLine2 + ", " + $formItem.Town + ", " + $formItem.Postcode
Date Calculations¶
// Current date (use the built-in function)
Current_Date
// Age from date of birth (years)
(new Date().getFullYear() - new Date($formItem.DateOfBirth).getFullYear())
// More accurate age (accounting for month/day)
(new Date().getFullYear() - new Date($formItem.DateOfBirth).getFullYear() -
(new Date().getMonth() < new Date($formItem.DateOfBirth).getMonth() ||
(new Date().getMonth() === new Date($formItem.DateOfBirth).getMonth() &&
new Date().getDate() < new Date($formItem.DateOfBirth).getDate()) ? 1 : 0))
// Days between two dates
Math.floor((new Date($formItem.EndDate) - new Date($formItem.StartDate)) / (1000 * 60 * 60 * 24))
// Percentage through lifecycle (from install date and lifespan in years)
(Math.floor((new Date() - new Date($formItem.InstallDate)) / (1000 * 60 * 60 * 24 * 365.25)) / ($formItem.LifeSpan || 1) * 100)
String Splitting (Pipe/Delimiter)¶
Useful for parsing SQLite builder+parser output:
// Split pipe-delimited string — get first segment
($formItem.z_QueryOutput ? $formItem.z_QueryOutput.split("|")[0] : "")
// Get second segment
($formItem.z_QueryOutput ? $formItem.z_QueryOutput.split("|")[1] : "")
// Get first comma segment from second pipe segment (CRM Class Level 1)
($formItem.z_QueryOutput ? $formItem.z_QueryOutput.split("|")[1].split(",")[0] : "")
Current User¶
Warning: The name returned by
UserDisplayName()may be the app name, AD stored name, or backend name depending on configuration. Test in context before relying on it.
Conditional / Ternary¶
// Basic ternary
($formItem.SomeFlag == "Yes" ? "Shown text" : "Hidden text")
// Nested ternary
($formItem.Status == "Active" ? "Active" : ($formItem.Status == "Pending" ? "Pending" : "Unknown"))
// Check if field has a value
($formItem.FieldName ? "Has value" : "Empty")
Arrow Functions¶
Arrow functions can be used within a single-line expression for map/filter/reduce operations:
// Map over an array (if field contains array data)
$formItem.Items.map(x => x.Name).join(", ")
// Filter and count
$formItem.Items.filter(x => x.Status == "Active").length
Regex Patterns¶
National Insurance Number¶
^((A[A-BEHKLMPRSTWX-Z])|(B[A-BEHKLMT])|(C[A-BEHKLR])|(E[A-BEHKLMPRSTWXYZ])|(GY)|(H[A-BEHKLMPRSTWXYZ])|(J[A-BCEGHJKLMNPRSTWXYZ])|(K[A-BEHKLMPRSTWXYZ])|(L[A-BEHKLMPRSTWXYZ])|(M[AWX-X])|(N[A-BEHLMPRSWXYZ])|(O[A-BEHKLMPRSX])|(P[A-BCEGHJLMNPRSTWXY])|(R[A-BEHKMPRSTWXYZ])|(S[A-BCGHJKLMNPRSTWXYZ])|(T[A-BEHKLMPRSTWXYZ])|(W[A-BEKLMP])|(Y[A-BEHKLMPRSTWXYZ])|(Z[A-BEHKLMPRSTWXY]))\d{6}([A-D]|s)$/gm
UK Telephone Number¶
^(?:(?:0(?:0|11)\s?|+)44\s?(?:0\s?)?|0)(?:\d{2}\s?\d{4}\s?\d{4}|\d{3}\s?\d{3}\s?\d{3,4}|\d{4}\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\s?\d{4,5}|8(?:00\s?11\s?11|45\s?46\s?4\d))$
Group Filtering¶
To filter a data grid group to show only rows matching a condition:
- Use the Group Filter property on the
GroupDataGridElement - The filter expression is a JavaScript boolean, same syntax as other formulas
- Example: show only "Active" components: