> ## Documentation Index
> Fetch the complete documentation index at: https://docs.azalt.co/llms.txt
> Use this file to discover all available pages before exploring further.

# FormElement

> Fields and UI components, with types, periods, and validation

Form elements are the building blocks of a form. Each element defines type, label, key, period, validation, and optional unit/conditions.

## FormElement Types & Capabilities

**Data Collection Elements:**

* **NUMBER**: Numeric inputs with unit integration, decimal precision, min/max validation
* **SHORT\_TEXT**: Single-line text with character limits and format validation
* **LONG\_TEXT**: Multi-line text areas for descriptions and comments
* **SINGLE\_CHOICE**: Radio buttons with custom option values and labels
* **MULTIPLE\_CHOICE**: Checkboxes allowing multiple selections
* **FILE\_UPLOAD**: Document attachments with type restrictions and size limits

**UI & Organization Elements:**

* **TITLE**: Section headers with custom styling and hierarchy
* **PARAGRAPH**: Rich text content for instructions and descriptions
* **DIVIDER**: Visual separators for form organization
* **GROUP**: Collapsible sections for organizing related fields
* **PAGE**: Multi-page forms with navigation controls
* **IMAGE**: Embedded images for visual guidance

**Advanced Elements:**

* **ACTIVITY**: Custom calculations based on activity definitions (cannot use TIMESTAMP period)

## Data and periods

Values for each element are stored as FormElementSubmission rows within a FormSubmission. Period handling:

* YEARLY: `periodUnit = 1`
* MONTHLY: `periodUnit = 1..12`
* QUARTERLY: `periodUnit = 1..4`
* TIMESTAMP: requires a `recordedAt` UTC timestamp; `periodUnit` is derived from the recorded month

**Multiple Entry Support**: Handle multiple submissions per field/period (especially for external forms)

```
// Supplier A's data
FormElementSubmission { periodUnit: 6, sequence: 0, value: 850 }
// Supplier B's data
FormElementSubmission { periodUnit: 6, sequence: 1, value: 1200 }
// Internal estimate
FormElementSubmission { periodUnit: 6, sequence: 2, value: 1000 }
```

**Flexible Value Storage**: JSON-based `value` supports multiple data types

* Numbers: `1250.5`
* Text: `"Natural gas from certified supplier"`
* Arrays: `["Grid electricity", "Solar panels"]`
* Objects: `{"scope1": 450, "scope2": 280, "total": 730}`

## Configuration Options

**Units**: Associate units with elements for clear labeling and validation.

**Validation Rules**: Ensure data quality and consistency

* Required field enforcement
* Min/max value validation
* Format validation for text fields
* File type and size restrictions for uploads

**Conditional Logic**: Dynamic behavior based on other field values

* Show/hide elements based on responses
* Change validation rules conditionally
* Update available options dynamically

**Period Configuration**: YEARLY, MONTHLY, QUARTERLY, TIMESTAMP (TIMESTAMP not allowed for ACTIVITY).

**Distribution Mode (NUMBER)**: `total` or `snapshot`.

## Workflow status

Each saved value has a status (COMPLETED, APPROVED, REJECTED) based on the form/organization workflow. Approvals apply per value; for ACTIVITY elements, bulk status updates affect all rows of the same element and period within a submission.

## Real-World Examples

**Energy Consumption Field**:

* Type: NUMBER
* Unit: kWh
* Validation: Min 0, Max 1,000,000
* Period: Monthly
* Required: Yes

**Energy Source Selection**:

* Type: SINGLE\_CHOICE
* Options: \["Grid Electricity", "Solar", "Wind", "Natural Gas"]
* Conditional: Shows renewable details if solar/wind selected

**Supporting Documentation**:

* Type: FILE\_UPLOAD
* Accepted: PDF, Excel, CSV
* Max size: 10MB
* Required: No
* Metadata: Set `allowSupportingDocumentsUpload: true` when you want this element to expose the supporting-document drawer in public forms configured with `publicSupportingDocumentsMode = "opt-in"`. The builder exposes this as the **Allow supporting documents (public)** checkbox.

### Inline choice children

When you want a follow-up element to appear directly beneath the option that triggers it:

* Add a `show` condition with a single `equals` comparison targeting one `SINGLE_CHOICE` / `MULTIPLE_CHOICE` parent option (aggregator must stay `SINGLE`).
* Toggle **Inline under choice option** in the element settings (the toggle remains disabled until the condition qualifies).
* The renderer will inject the child beneath the selected option for every period (including TIMESTAMP rows). Legacy layouts remain unchanged for elements that do not enable `config.inlineChoiceDisplay`.

**Emissions Calculation**:

* Type: ACTIVITY
* Inputs: Fuel consumption, emission factor
* Output: Total CO2e emissions
* Auto-calculation: Yes
