Skip to content

[Formplayer] Support cross-field validation ($data) #304

@najuna-brian

Description

@najuna-brian

Description

Problem

Custom apps built on ODE currently lack two capabilities that are needed for robust data collection workflows:

  1. Cross-field validation There is no way to enforce that two fields in the same form hold the same value. For example, a QR code scanned at the start of a form should match the one scanned at the end to ensure data integrity across collection stages. Today, this can only be checked with client-side logic outside the form schema, which is fragile and inconsistent.

  2. Auto-computed fields Some fields need to be derived from other fields in real time (e.g., generating a compact identifier code from a combination of region, sector, and site selections). There is currently no generic mechanism for custom apps to declare these calculations each case requires formplayer changes or workarounds.

Proposed solution

1. Enable AJV $data references

AJV (the JSON Schema validator used by the formplayer) supports a $data keyword that allows schema rules to reference sibling field values. For example:

{ "const": { "$data": "1/initial_qr_code" } }

This would validate that a field's value equals the value of initial_qr_code — entirely declarable in schema.json with no custom code. This feature just needs to be switched on ($data: true in the AJV config).

2. Add a generic computed fields engine

Custom apps should be able to declare computed fields in ext.json:

"computedFields": {
  "formName": {
    "target_field": {
      "function": "myComputeFunction",
      "dependencies": ["fieldA", "fieldB", "fieldC"]
    }
  }
}

The formplayer would watch the listed dependencies for changes, call the registered extension function with the current form data, and write the result back to the target field. The computation logic lives in the custom app's extension module — the formplayer only provides the generic wiring.

Scope

  • formulus-formplayer: Enable $data in AJV; add computed fields processing in handleDataChange; update extension loading to handle computedFields metadata
  • formulus: Pass computedFields from ext.json through ExtensionService and FormplayerModal to the formplayer WebView
  • No custom app changes required in ODE itself custom apps opt in by adding rules to their own schema.json and ext.json

Acceptance criteria

  • $data references work in schema.json validation rules (e.g., const, minimum, maximum)
  • $data references work in ui.json visibility rules
  • Computed fields declared in ext.json are automatically calculated when dependencies change
  • Computed field values are persisted in the form data and saved with the record
  • No regressions in existing custom apps that do not use these features

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions