Skip to content

Calculated Fields and JavaScript in Forms


Rules

  • All formulas must be a single-line expression — no multi-line code or variable declarations.
  • If writing complex logic: write it multi-line first (in a text editor or GPT), then collapse to one line.
  • Use + for string concatenation — but be careful with integers and dates (see below).
  • Use || for OR, && for AND.
  • Use ? / : shorthand for conditionals.
  • Always bracket complex logic with ().

Field Types: Text vs Numeric

Understanding field type behaviour is critical — many bugs come from mixing types.

Text Fields (String)

  • Designed to hold string data. Numeric data can be stored in a text field, but this changes the field's behaviour.
  • Addition (+) on a text field behaves as concatenation, not arithmetic.
  • The SUM calculation across group elements does not handle string fields — it will not concatenate and will not aggregate numerically.
  • At the time of writing, there is no reliable, scalable way to concatenate text across group elements in Versaa.
  • Text fields are incompatible with numeric field types — explicit type conversion is needed to get numeric behaviour from a text field. This can be done inside a calculation by explicitly assigning to a numeric data type.

Numeric Fields (INT)

  • Numeric fields (e.g. INT) support mathematical operations: aggregation (SUM) and subtraction work correctly.
  • JavaScript in calculations can treat a numeric field as either text or a number — be explicit about which behaviour you need.
  • Only numbers are acceptable in an INT field — inserting non-numeric data will cause errors.
  • Numeric precision may be lost on an INT field — avoid using INT for values that need decimal precision.

Basic Patterns

String concatenation:

$formItem.field1 + " " + $formItem.field2

Conditional (inline if):

$formItem.field1 ? "Value if true" : "Value if false"

Combining conditions:

($formItem.field1 && $formItem.field2) ? "Both true" : "At least one false"


Integer / Date Fields

Integer fields and text fields look identical in the Aareon Mobile app but behave differently in the database. This causes hard-to-diagnose bugs.

  • Never concatenate integers or date/time fields directly with text. Create a text field copy (e.g., z_InstanceNameA) first.
  • During development: add a type label to field captions (Age [int] vs Age [str]) to tell them apart at a glance. Remove before deploying to Live.
// Wrong — may cause bugs
$formItem.integerField + " items"

// Right — convert first
$formItem.integerField.toString() + " items"

Formatting a Date Field as a String

Date/DateTime FormItems (type="Date" or type="DateTime") expose a JavaScript Date object at formula evaluation time. You cannot use String(dateField) or .toString() — these produce values like "Mon Dec 14 2037 00:00:00 GMT+0100 (BST)", and .split(" ")[0] gives the day-of-week ("Mon"), not the date.

Also do NOT use GetSelectedItemValue on a date column — it returns the same JS Date object.

Correct pattern — use Date methods on $formItem

// Produces "14/12/2007" (D/M/YYYY, no zero-padding)
$formItem.InstallDate
  ? $formItem.InstallDate.getDate() + "/" + ($formItem.InstallDate.getMonth()+1) + "/" + $formItem.InstallDate.getFullYear()
  : ""

Collapsed to one line (required by Versaa):

$formItem.InstallDate?$formItem.InstallDate.getDate()+"/"+($formItem.InstallDate.getMonth()+1)+"/"+$formItem.InstallDate.getFullYear():""

Note: .getMonth() is zero-based — January = 0, so always add 1.

Use a z_ String helper field for document templates

The Word Connector renderer reads from the saved task XML, not from live formula evaluation. To get a formatted date into a PDF document:

  1. Add a z_FieldName_Fmt String FormItem with the formula above
  2. Set archivable=True (so the value is saved to task XML)
  3. Set availableForDocumentRendering=True (so it appears as valid in the template)
  4. Bind the template placeholder to z_FieldName_Fmt, not the original date field

See forms/word-connector-templates.md for full detail.

Formula Expression length limit (~178 chars)

The Expression text of a formula is stored in a SQL column with a maximum length of approximately 178 characters. Exceeding this causes import error:

8152: String or binary data would be truncated

Keep date formatting expressions as short as possible. The pattern above is ~133–151 chars depending on field name length — safely within the limit.


Date of Birth → Age Calculation

new Date().getFullYear() - new Date(QL_DateOfBirth_1).getFullYear() - (new Date() < new Date(new Date().getFullYear(), new Date(QL_DateOfBirth_1).getMonth(), new Date(QL_DateOfBirth_1).getDate()) ? 1 : 0)

Replace QL_DateOfBirth_1 with your actual DOB field name. Accounts for whether the birthday has occurred yet this year.


String Formula Type (Email, Document Names, Subjects)

Several platform form items use Formula → Calculations → String type, not JavaScript. Syntax differs:

  • Literal text in double speech marks: "some text"
  • Form item values referenced by name (use the value picker: V = value, N = name)
  • Use + to concatenate
  • Always add spaces inside speech marks at text boundaries — otherwise words run together

Document name (unique per submission):

"Component Replacement Request " + [V.QL_PropertyID] + " " + currentDate()

Email subject:

"Component replacement request for " + [V.QL_PropertyID]

Email body:

"Attached is the " + [V.component] + " component replacement request for property reference " + [V.QL_PropertyID] + " on " + [QL_StartForm].toString("DD")

Email attachment filename:

[V.form_document_name] + ".pdf"

.toString("DD") for dates — when concatenating a date form item into a string, append .toString("DD") to control format. Without it, the raw value may not concatenate cleanly.

Tip: Open an existing form that already sends email documents (e.g., Written Scheme Review, Building Safety Check) and copy the expression — adapt text/field references for your form.