Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

User guide for creating powerful validation rules using expression-based validation in wizard steps.

Overview

Advanced Validation Expressions allow you to create complex validation rules that go beyond simple required/min/max checks. Using a JavaScript-like syntax, you can validate:
  • Age requirements
  • Date comparisons
  • Conditional required fields
  • Pattern matching
  • Cross-field validation
  • Custom business rules

Getting Started

Accessing Expression Validation

  1. Open a wizard template in the Builder
  2. Select a step
  3. Go to the Validation tab
  4. Click the Advanced Expressions sub-tab

Your First Expression

Let’s create a simple age validation:
age(date_of_birth) >= 18
This expression:
  • Takes the date_of_birth field value
  • Calculates the age in years
  • Checks if it’s 18 or older

Expression Syntax

Basic Structure

function(field_name) operator value

Operators

OperatorDescriptionExample
==Equalsstatus == "active"
!=Not equalsstatus != "inactive"
>Greater thanage(dob) > 21
>=Greater or equalamount >= 100
<Less thanquantity < 1000
<=Less or equalyears_since(hire_date) <= 5
&&Logical ANDa > 0 && b > 0
||Logical ORa > 0 || b > 0
!Logical NOT!is_empty(email)

Combining Expressions

Use && (AND) and || (OR) to combine multiple conditions:
// Both must be true
age(dob) >= 18 && !is_empty(email)

// Either can be true
is_empty(phone) || is_valid_phone(phone)

// Complex combination
(age(dob) >= 18 && is_employed) || has_guardian_consent

Available Functions

Date Functions

FunctionDescriptionExample
age(date)Years since dateage(date_of_birth) >= 18
years_since(date)Years since dateyears_since(hire_date) >= 1
months_since(date)Months since datemonths_since(start_date) >= 6
days_since(date)Days since datedays_since(last_review) <= 365
is_before(date1, date2)date1 < date2is_before(start_date, end_date)
is_after(date1, date2)date1 > date2is_after(hire_date, training_date)
today()Current dateis_before(deadline, today())

String Functions

FunctionDescriptionExample
is_empty(value)Check null/empty!is_empty(email)
is_not_empty(value)Check has valueis_not_empty(email)
len(value)String lengthlen(name) >= 2
matches(value, pattern)Regex match (safe)matches(zip, "^\\d{5}$")
starts_with(value, prefix)Check prefixstarts_with(phone, "+1")
ends_with(value, suffix)Check suffixends_with(email, ".edu")
contains(value, substring)Check substringcontains(notes, "urgent")

Validation Functions

FunctionDescriptionExample
is_valid_email(value)Email formatis_valid_email(email)
is_valid_phone(value)Phone formatis_valid_phone(phone)
is_valid_ssn(value)SSN formatis_valid_ssn(ssn)
is_valid_zip(value)US ZIP formatis_valid_zip(zip_code)

Number Functions

FunctionDescriptionExample
is_between(val, min, max)Range checkis_between(age, 18, 65)

Comparison Functions

FunctionDescriptionExample
eq(a, b)Equalseq(status, "active")
neq(a, b)Not equalsneq(status, "closed")
gt(a, b)Greater thangt(age, 18)
gte(a, b)Greater or equalgte(score, 70)
lt(a, b)Less thanlt(quantity, 100)
lte(a, b)Less or equallte(price, 1000)

Conditional Functions

FunctionDescriptionExample
required_if(condition, field)Conditional requiredrequired_if(is_employed, employer_name)
one_of(value, options)Value in listone_of(status, ["active", "pending"])
not_one_of(value, options)Value not in listnot_one_of(role, ["admin", "super"])
all(a, b, ...)All truthyall(has_consent, is_adult)
any(a, b, ...)Any truthyany(has_phone, has_email)
not(value)Logical NOTnot(is_locked)

Common Patterns

Age Verification

// Must be 18 or older
age(date_of_birth) >= 18

// Must be between 18 and 65
is_between(age(date_of_birth), 18, 65)

// Under 18 requires guardian
age(date_of_birth) >= 18 || !is_empty(guardian_name)

Date Range Validation

// End date must be after start date
is_after(end_date, start_date)

// Event must be in the future
is_after(event_date, today())

// Must be within 90 days
days_since(submission_date) <= 90

Conditional Required Fields

// Employer required if employed
required_if(is_employed, employer_name)

// Phone OR email required
!is_empty(phone) || !is_empty(email)

// Address required if not same as billing
required_if(!same_as_billing, shipping_address)

Format Validation

// US phone format (10 digits)
matches(phone, "^\\d{10}$")

// ZIP code (5 or 9 digits)
matches(zip, "^\\d{5}(-\\d{4})?$")

// Strong password (8+ chars, number, special)
len(password) >= 8 && matches(password, "[0-9]") && matches(password, "[!@#$%]")

Cross-Field Validation

// Confirm password matches
password == confirm_password

// Total must equal sum of parts
total == (subtotal + tax)

// End date at least 30 days after start
days_since(start_date) >= 30 || is_after(end_date, start_date)

Creating Expression Rules

Step-by-Step

  1. Open Validation Panel: Select a step and click “Validation” tab
  2. Switch to Advanced: Click “Advanced Expressions” sub-tab
  3. Add Rule: Click “Add Expression Rule”
  4. Write Expression: Enter your validation expression
  5. Set Error Message: Define the message shown when validation fails
  6. Set Timing: Choose when to validate (on change, blur, or submit)
  7. Test: Use the Test Runner to verify

Rule Properties

PropertyDescription
ExpressionThe validation logic
Error MessageShown when validation fails
TimingWhen to run: on_change, on_blur, on_submit
PriorityOrder of execution (lower runs first)
EnabledToggle rule on/off without deleting

Testing Expressions

Using the Test Runner

  1. Click Test Expressions button
  2. Enter sample values for each field
  3. Click Run Tests
  4. View pass/fail results for each rule

Test Runner Features

  • Field Inputs: Auto-generated from step fields
  • Quick Fill: Sample data suggestions
  • Results Panel: Shows which rules pass/fail
  • Error Preview: See exact error messages

Testing Tips

  1. Test both valid and invalid inputs
  2. Test edge cases (empty, null, boundaries)
  3. Test with realistic data
  4. Verify error messages are helpful

Error Messages

Writing Good Messages

Bad: “Invalid”
Good: “Date of birth indicates you must be at least 18 years old”
Bad: “Required”
Good: “Employer name is required when employment status is ‘Employed‘“

Message Variables

You can reference field values in messages (coming soon):
"Age {{age(date_of_birth)}} does not meet the minimum requirement of 18"

Best Practices

Expression Design

  1. Keep It Simple: Break complex rules into multiple expressions
  2. Be Specific: Target specific fields, not entire forms
  3. Handle Empty: Always consider null/empty cases
  4. Use Parentheses: Make precedence explicit

Performance

  1. Timing Matters: Use on_submit for expensive validations
  2. Avoid Redundancy: Don’t repeat standard validations
  3. Order by Priority: Put quick-fail checks first

Maintenance

  1. Document Rules: Use clear error messages as documentation
  2. Group Related Rules: Keep related validations together
  3. Test After Changes: Always re-test after modifications
  4. Version Control: Track changes in template versions

Healthcare & PHI Compliance

PHI Field Naming Guidelines

When creating validation expressions that may touch PHI/PII:
  1. Use Generic Field Names: Prefer patient_id, resident_id, client_id over revealing field names
  2. Avoid Revealing Names: Never use field names that expose sensitive data types (avoid ssn, medical_record_number, diagnosis_code)

Expression Audit Requirements

All expressions touching PHI fields must be:
  1. Reviewed by a compliance officer before deployment
  2. Logged for creation/modification with user ID and timestamp
  3. Never log actual PHI values - only log field references and expression text

Error Message Rules (Critical)

Functions like age(), matches(), required_if() must:
  • Never include actual field values in error messages
  • Use generic messages: “Age requirement not met” not “Your age of 17 does not meet…”
  • Avoid revealing field contents in validation failures

Timing Recommendations for PHI

  • Use on_submit: For PHI field validations to minimize data exposure during typing
  • Avoid on_change: Real-time validation can increase attack surface

Access Control

  • Only users with appropriate permissions should edit expressions
  • Expression editing should be restricted to form administrators
  • Implement retention policies for expression audit logs (recommended: 7 years for healthcare)

Security Considerations

Safe by Design

Expression validation is sandboxed:
  • No eval() or code execution
  • No access to global objects
  • No network requests
  • No file system access

What’s Blocked

  • JavaScript code injection
  • Function definitions
  • Variable assignments
  • External references

What’s Allowed

  • Field references by name
  • Approved validation functions
  • Operators (comparison, logical)
  • Literal values (strings, numbers, booleans)

Troubleshooting

Common Errors

ErrorCauseFix
”Unknown function”Typo or unsupported functionCheck function name spelling
”Unknown field”Field name not foundVerify field name property
”Syntax error”Malformed expressionCheck operators and parentheses
”Type mismatch”Wrong value typeEnsure correct field types

Debugging Tips

  1. Simplify: Reduce to smallest failing case
  2. Test Runner: Use to isolate issues
  3. Check Field Names: Match exactly (case-sensitive)
  4. Review Syntax: Watch for missing quotes/parentheses

See Also