docs

Formplayer Component Reference

Complete technical reference for the Formplayer form rendering component.

:::info[Authoritative Reference Available]

For the complete, authoritative contract defining all supported JSON Schema features, UI schema structure, validation rules, and behavioral guarantees, see the Formplayer Contract.

:::

Overview

Formplayer is a React web application that renders JSON Forms and provides the dynamic form interface for data collection. It runs within WebViews in the Formulus mobile app and communicates with the native app through a JavaScript bridge.

Supported Schema & UI Profile

Critical: ODE Formplayer intentionally supports a safe, predictable subset of JSON Schema and JSON Forms. Forms outside this profile may load but are not guaranteed to work.

Supported JSON Schema Features

Feature Supported Notes
type string, number, integer, boolean, object, array
properties Object property definitions
required Array of required property names
minimum / maximum Literal numbers only (e.g., "minimum": 0)
minLength / maxLength String length constraints
pattern Regular expression patterns
format email, date, date-time, uri, uuid
enum Array of allowed values
enumNames Display names for enum values
oneOf Recommended for single-choice selections
title Field display title
description Field description/help text
default Default values
const Constant values (used in rules)
$data Will crash - not supported
if / then / else Not supported in rule conditions
$ref ⚠️ Limited support - use with caution
allOf / anyOf ⚠️ Limited support - use with caution

Supported UI Schema Elements

Element Required Fields Notes
SwipeLayout type, elements[] Root layout (required or auto-wrapped)
VerticalLayout type, elements[] Vertical field arrangement
HorizontalLayout type, elements[] Horizontal field arrangement
Group type, label, elements[] Grouped fields with label
Control type, scope Field control (scope must exist in schema)
Label type, text Text label element

Unsupported / Unsafe Features

❌ JSON Schema:

❌ UI Schema:

⚠️ Common Pitfalls:

Safe Form Patterns

✅ Recommended Structure:

{
  "schema": {
    "type": "object",
    "properties": {
      "field1": { "type": "string", "title": "Field 1" },
      "field2": { "type": "integer", "minimum": 0, "maximum": 100 }
    },
    "required": ["field1"]
  },
  "uischema": {
    "type": "SwipeLayout",
    "elements": [
      {
        "type": "VerticalLayout",
        "elements": [
          {
            "type": "Control",
            "scope": "#/properties/field1"
          },
          {
            "type": "Control",
            "scope": "#/properties/field2"
          }
        ]
      }
    ]
  }
}

❌ Unsafe Patterns:

{
  "schema": {
    "properties": {
      "field1": { "type": "string" }
    }
  },
  "uischema": {
    "type": "Control",
    "scope": "#/properties/missingField"  //  Field doesn't exist
  }
}
{
  "schema": {
    "properties": {
      "value": {
        "type": "number",
        "minimum": { "$data": "#/minValue" }  //  $data not supported
      }
    }
  }
}

Architecture

Technology Stack

Component Structure

formulus-formplayer/
├── src/
│   ├── App.tsx                    # Main application component
│   ├── FormLayout.tsx             # Form layout renderer
│   ├── QuestionShell.tsx         # Question wrapper component
│   ├── *QuestionRenderer.tsx     # Question type renderers
│   ├── FormulusInterface.ts       # Bridge interface definition
│   └── theme.ts                   # Theming configuration
├── public/
│   └── formulus-load.js          # API loading script
└── build/                         # Production build output

Core Responsibilities

Formplayer is responsible for:

  1. Form Rendering: Render forms based on JSON schema and UI schema
  2. Data Collection: Capture user input through various question types
  3. Validation: Validate form responses against schema rules
  4. Observation Management: Create, edit, and delete observations
  5. Draft Management: Save and load draft observations

Integration with Formulus

Initialization

Formplayer is initialized by the Formulus app with:

Communication Model

┌─────────────────┐         ┌──────────────────┐
│   Formulus      │         │   Formplayer     │
│   (Native)       │◄───────►│   (WebView)      │
│                 │         │                  │
│  • Database     │         │  • Form Render   │
│  • Sync Engine  │         │  • Validation    │
│  • API Bridge   │         │  • User Input    │
└─────────────────┘         └──────────────────┘

JavaScript Interface

Formplayer exposes methods to custom applications and receives configuration from Formulus.

Available Methods

addObservation(formType, initializationData)

Open a form to create a new observation.

window.formulus.formplayer.addObservation('survey', {
  participantId: '123',
  location: 'Field Site A'
});

Parameters:

editObservation(formType, observationId)

Open a form to edit an existing observation.

window.formulus.formplayer.editObservation('survey', 'obs-123');

Parameters:

deleteObservation(formType, observationId)

Delete an observation.

window.formulus.formplayer.deleteObservation('survey', 'obs-123');

Parameters:

Question Types

Formplayer supports various question types through custom renderers:

Text Input

Number Input

Date and Time

Selection

Form UX (2026)

See Form design guide for ui.json examples.

Boolean

Media Capture

Special Input

Form Rendering

Schema Processing

Formplayer processes JSON schemas to:

  1. Parse Schema: Extract form structure and validation rules
  2. Process UI Schema: Apply layout and presentation rules
  3. Generate Form: Create form components based on schema
  4. Apply Validation: Set up validation rules

Layout System

Forms can use different layout strategies:

Validation

Schema Validation

Formplayer validates form responses against:

Custom Validation

Custom validation rules can be added:

Draft Management

Saving Drafts

Formplayer can save incomplete forms as drafts:

  1. Auto-save: Periodically save form state
  2. Manual Save: User-triggered draft save
  3. Local Storage: Drafts stored in WebView storage

Loading Drafts

When opening a new root observation, Formplayer may show a draft selector if local drafts exist. Custom apps can bypass this with openFormplayer(formType, params, savedData, { skipDraftSelection: true }) when they orchestrate the session (for example after preparing defaultData programmatically). Sub-observation sessions and edits with savedData never show the picker.

When editing an observation:

  1. Load Data: Fetch observation data from Formulus
  2. Populate Form: Pre-fill form fields with data
  3. Restore State: Restore form state and validation

Theming

Theme Configuration

Formplayer uses a theme system for styling:

Custom Theming

Themes can be customized:

Building and Deployment

Development Build

# Install dependencies (build @ode/tokens first)
cd ../packages/tokens && pnpm install && pnpm run build && cd ../formulus-formplayer
pnpm install

# Start development server
pnpm start

# Opens at http://localhost:3000 (or Vite's printed port)

Production Build

# Build and copy into Formulus (and ODE Desktop)
pnpm run build:copy

# Build for web only
pnpm run build

Build Output

The build process:

  1. Compiles TypeScript: Transpiles to JavaScript
  2. Bundles Assets: Combines CSS and images
  3. Minifies Code: Optimizes for production
  4. Copies to Formulus: Copies build to Formulus app

Integration with Custom Applications

Loading Formplayer

Custom applications can use Formplayer:

<script src="formulus-load.js"></script>
<script>
  async function openForm() {
    const api = await getFormulus();
    await api.addObservation('survey', {});
  }
</script>

Formplayer API

The Formplayer API is injected into custom app WebViews:

// Access Formplayer methods
window.formulus.formplayer.addObservation('survey', {});

Question Type Renderers

Core Renderers

Formplayer includes core question type renderers:

Custom Renderers

Custom renderers can be added:

  1. Create Renderer Component: Implement question type component
  2. Register Renderer: Add to Formplayer configuration
  3. Use in Forms: Reference in form schema

Error Handling

Validation Errors

Formplayer displays validation errors:

Runtime Errors

Error handling for:

Performance

Optimization Strategies

Best Practices

Development

Local Development

  1. Start Dev Server: pnpm start
  2. Open Browser: Navigate to http://localhost:3000
  3. Hot Reload: Changes reflect automatically

Testing