Skip to main content
NCZ forms support two complementary mechanisms for ensuring data quality and automating calculations: validation rules that reject invalid input before submission, and calculation formulas that derive field values automatically from other answers. This page is a full reference for both systems. Validation rules are defined per question (or per table column) in the form configuration. Formulas are attached to calculated fields using the calculationFormula property, and the formula engine re-evaluates them whenever a dependency changes.

Validation rules

Validation rules are attached to individual questions or table columns using the validationRules object in the form configuration JSON.

Required field

Makes a field mandatory. The form cannot be submitted until the field contains a value.
Use isRequired: true at the question level for standard questions. For table columns, use column.isRequired: true on the column definition instead.

Table column validations

Table questions support the same validation rules on a per-column basis. Define validationRules inside each column object in the tableConfig.columns array.
Validation runs on blur — errors appear when the user leaves a field, not while they are typing. This applies to both top-level questions and table cells.

Calculation formulas

Calculated fields derive their value automatically using a formula expression. Set isCalculated: true and provide a calculationFormula string. The engine re-evaluates the formula each time any referenced field changes.

Basic syntax

Use curly braces {} to reference the value of another question by its questionKey:

Arithmetic operations

All standard arithmetic operators are supported, and expressions can be grouped with parentheses:

Mathematical functions

Example: total emissions across scopes
Example: round converted emissions to 2 decimal places
Function names are case-insensitive. SUM, Sum, and sum all work identically.

Conditional logic

IF / THEN / ELSE

Comparison operators:

IF / ELSEIF / ELSE

Chain multiple conditions using ELSEIF:

CASE / WHEN

Use CASE to match a field against a set of fixed values — cleaner than a long ELSEIF chain when you are mapping specific codes to results:
Prefer CASE over deeply nested ELSEIF chains when you are doing value lookups. It is easier to read and maintain.

Referencing option labels

When a question uses a predefined option list (dropdown or select), each option has an internal value and a display label. By default {fieldKey} returns the internal value. Append .label to get the human-readable display label instead:

Table calculations

Table questions store multiple rows of structured data. The formula engine provides several ways to reference that data.

Syntax reference

Examples


URL query parameters

The param() function lets you read values from the URL query string and use them inside formulas. This is useful for pre-filling context information, applying region-specific factors, or integrating with external systems that append reference IDs to form links.

Syntax

  • Returns the string value of the named query parameter.
  • Returns an empty string "" if the parameter is absent.
  • Handles both numeric and text values automatically.

Basic parameter usage

URL: ?certId=CERT-2024-001 Result: "CERT-2024-001"
URL: ?certId=CERT-2024-001&locationId=LOC-789 Result: "Submitting data for Certificate: CERT-2024-001 at Location: LOC-789"

Parameters in calculations

URL: ?emissionFactor=0.85 Result: User’s energy consumption × 0.85
Result: Uses the URL parameter if provided; otherwise defaults to 0.85.

Parameters in conditional logic

URL: ?scheme=gold Result: Determines the certification level using both the URL scheme and the user’s entered score.
URL: ?region=EU Result: 1.2 (20% premium applied for the EU region)

Complex parameter examples

URL: ?supplierType=direct&discount=0.9 Result: Calculates cost based on the supplier type and discount factor from the URL.
URL: ?adjustmentFactor=1.15 Result: Sum of the CO2 column multiplied by the adjustment factor from the URL.

Common use cases for URL parameters

Parameter security

URL parameters are visible to the user and can be modified. Never rely on them for security decisions, access control, or pricing without independent server-side validation.
Safe uses of param():
  • Capturing reference IDs (validated on the backend)
  • Displaying context information to the user
  • Pre-filling convenience fields
  • Non-sensitive calculations
Unsafe uses of param():
  • Bypassing security or access checks
  • Determining prices without backend validation
  • Transmitting sensitive data

Complex formula examples

These examples demonstrate how the formula syntax elements combine in real-world carbon management scenarios.
Three-tier pricing: first 1,000 tCO2e at £15, next 4,000 at £12, everything above 5,000 at £10.
Guards against division by zero when the baseline is zero.

Important notes

Validation behaviour

  • Validation errors appear on blur — when the user leaves a field, not while they are typing.
  • Use isRequired: true at the question level; use column.isRequired: true for table column definitions.
  • Remember to double-escape backslashes in JSON regex patterns: write \\d to represent the regex \d.
  • File sizes must be specified in bytes: 1 MB = 1048576, 5 MB = 5242880.

Formula execution and correctness

  • Execution order — the engine re-evaluates a formula each time any of its referenced fields change. Ensure source fields are answered before calculated fields that depend on them.
  • Circular dependencies — do not create formulas that reference each other, directly or indirectly. Circular references cause evaluation loops and must be avoided.
  • String literals — wrap string constants in double quotes inside the formula string: "Active", "USA".
  • Case sensitivity — function names are case-insensitive (SUM, Sum, sum all work).
  • Division by zero — always guard division operations with an IF check when the denominator could be zero, as shown in the percentage change example above.
  • Floating-point precision — use ROUND on final results to avoid displaying long decimal tails caused by floating-point arithmetic.
  • Table data access — use the tableKey[rowIndex].columnKey syntax for specific cells, or COLUMN_SUM / ROW_SUM helper functions for aggregates.
  • URL parametersparam("name") returns an empty string when the parameter is absent; always provide a fallback using an IF check if the parameter is required for a numeric calculation.

Performance guidance

  • Keep individual formulas simple and readable. Break complex calculations into a chain of intermediate calculated fields.
  • Prefer CASE over long ELSEIF chains when mapping a fixed set of values.
  • Apply ROUND to final output fields rather than rounding at each intermediate step.