# Reference: Form Controls

Form controls live inside a `<GroupElement>` inside a `<GroupedElementsArea>`. Each control has a
`<Bindings>` block with one or more `<Resource>` (label/icon) and `<Binding>` (value) elements.

Real files with form controls:

-   `src/Visit/PR/Visit_Reschedule/Visit_RescheduleUI.userinterface.xml`
-   `src/Visit/PR/visit_Details/visit_DetailsUI.userinterface.xml`

---

## GroupElement (Form Section Container)

Groups a set of related fields under an optional section header.

```xml
<GroupElement name="InfoGroup">
  <Bindings>
    <!-- Section header label; use defaultLabel=" " (space) to suppress header -->
    <Resource target="Title" type="Label" id="InfoGroupId" defaultLabel="Information" />
  </Bindings>
  <!-- Form fields go here -->
</GroupElement>
```

Real example: `VisitInfoGroup` in `Visit_RescheduleUI.userinterface.xml` (line 21).

---

## InputArea (Single-Line Text Field)

```xml
<!-- Editable -->
<InputArea name="CustomerName">
  <Bindings>
    <Resource target="Label" type="Label" id="CustomerNameLabelId" defaultLabel="Customer" />
    <Binding target="Value" binding="ProcessContext::Bo.customerName" bindingMode="TWO_WAY" />
  </Bindings>
</InputArea>

<!-- Read-only: use disabled="true" + ONE_WAY -->
<InputArea name="AccountId" disabled="true">
  <Bindings>
    <Resource target="Label" type="Label" id="AccountLabelId" defaultLabel="Account" />
    <Binding target="Value" type="Text" binding="ProcessContext::Bo.accountName" bindingMode="ONE_WAY" />
  </Bindings>
</InputArea>
```

Real example: `AccountId` in `visit_DetailsUI.userinterface.xml` (line 11).

---

## InputAreaMultiLine (Multi-Line Text Area)

```xml
<InputAreaMultiLine name="Description" noOfRows="3">
  <Bindings>
    <Resource target="Label" type="Label" id="DescriptionLabelId" defaultLabel="Description" />
    <Binding target="Value" type="Text" binding="ProcessContext::Bo.description" bindingMode="TWO_WAY" />
  </Bindings>
</InputAreaMultiLine>
```

`noOfRows` controls the visible height. Real example: `Description` in `visit_DetailsUI.userinterface.xml` (line 43).

---

## DatePickerField

```xml
<DatePickerField name="StartDate">
  <Bindings>
    <Resource target="Label" type="Label" id="StartDateLabelId" defaultLabel="Start Date" />
    <Binding target="Value" binding="ProcessContext::Bo.startDate" bindingMode="TWO_WAY" />
  </Bindings>
</DatePickerField>
```

-   Binds to a `DomDate` or `DomDateTime` property.
-   Often paired with `TimePickerField` inside a `<Merger>`.

Real example: `VisitStartDate` in `Visit_RescheduleUI.userinterface.xml` (line 26).

---

## TimePickerField

```xml
<TimePickerField name="StartTime">
  <Bindings>
    <Binding target="Value" binding="ProcessContext::Bo.startTime" bindingMode="TWO_WAY" />
  </Bindings>
</TimePickerField>
```

-   When inside a `<Merger>`, the label is provided by the `<DatePickerField>` (the Merger's `labelHandling="Combined"` merges both labels).
-   Binds to a `DomTime` property.

Real example: `TimeFrom` in `Visit_RescheduleUI.userinterface.xml` (line 32).

---

## Merger (Two Fields Side-by-Side)

Combines two controls horizontally. Most common use: date + time picker.

```xml
<Merger name="StartDateTimeMerger" pattern="twoInputControls"
        labelHandling="Combined" separator="," leftRatio="5" rightRatio="5">
  <DatePickerField name="StartDate">
    <Bindings>
      <!-- Combined label goes on the DatePickerField when labelHandling="Combined" -->
      <Resource target="Label" type="Label" id="StartDateTimeId" defaultLabel="Start Date/Time" />
      <Binding target="Value" binding="ProcessContext::Bo.startDate" bindingMode="TWO_WAY" />
    </Bindings>
  </DatePickerField>
  <TimePickerField name="StartTime">
    <Bindings>
      <Binding target="Value" binding="ProcessContext::Bo.startTime" bindingMode="TWO_WAY" />
    </Bindings>
  </TimePickerField>
</Merger>
```

-   `pattern="twoInputControls"` — always this value for a two-field merger
-   `labelHandling="Combined"` — single label from first child; `labelHandling="Own"` — each child has its own label
-   `leftRatio` / `rightRatio` — width split (5+5 = equal halves; 7+3 = 70/30)

Real example: `StartDateMerger` in `Visit_RescheduleUI.userinterface.xml` (lines 25-37).

---

## SelectionBox (Dropdown / Combo)

Displays a picklist backed by a toggle (local lookup table).

```xml
<SelectionBox name="Status">
  <Bindings>
    <Resource target="Label" type="Label" id="StatusLabelId" defaultLabel="Status" />
    <!-- DataSource points to the toggle id that drives the dropdown options -->
    <Binding target="DataSource" toggleId="VisitStatus" bindingMode="ONE_WAY" />
    <Binding target="Value" type="Text" binding="ProcessContext::Bo.status" bindingMode="TWO_WAY" />
  </Bindings>
</SelectionBox>

<!-- Read-only dropdown -->
<SelectionBox name="StatusReadOnly" disabled="true">
  <Bindings>
    <Resource target="Label" type="Label" id="StatusROLabelId" defaultLabel="Status" />
    <Binding target="DataSource" toggleId="VisitStatus" bindingMode="ONE_WAY" />
    <Binding target="Value" type="Text" binding="ProcessContext::Bo.status" bindingMode="ONE_WAY" />
  </Bindings>
</SelectionBox>
```

-   `toggleId` references an application toggle (picklist) by its ID.
-   For editable: `bindingMode="TWO_WAY"` on the Value binding.

Real example: `Status` in `visit_DetailsUI.userinterface.xml` (line 81).

---

## Lookup (Reference Display Field)

Read-only field showing a referenced entity's attribute (e.g., customer name from a luCustomer lookup).

```xml
<Lookup name="Customer" disabled="true">
  <Bindings>
    <Resource target="Label" type="Label" id="CustomerLabelId" defaultLabel="Customer" />
    <Binding target="Value" binding="ProcessContext::Bo.luCustomer.name" bindingMode="ONE_WAY" />
  </Bindings>
</Lookup>
```

-   Always `disabled="true"` — Lookup is a display-only widget.
-   The binding path traverses into the BO's ObjectLookup: `.lu<Name>.<property>`.

---

## Stepper (Numeric with +/- Buttons)

```xml
<Stepper name="Discount" minValue="0" maxValue="100">
  <Bindings>
    <Resource target="Label" type="Label" id="DiscountLabelId" defaultLabel="Discount %" />
    <Binding target="Value" type="Decimal" formatV2="3.1"
             binding="ProcessContext::Bo.discount" bindingMode="TWO_WAY" />
    <Binding target="StepSize" value="0.1" />
  </Bindings>
</Stepper>
```

-   `formatV2="3.1"` → 3 digits total, 1 decimal place
-   `StepSize` binding controls increment amount

---

## CheckBoxField

```xml
<CheckBoxField name="IsActive">
  <Bindings>
    <Resource target="Label" type="Label" id="IsActiveLabelId" defaultLabel="Active" />
    <Binding target="Value" binding="ProcessContext::Bo.isActive" bindingMode="TWO_WAY" />
  </Bindings>
</CheckBoxField>
```

Binds to a `DomBool` property.

---

## Binding Modes for Form Controls

| Scenario                        | `bindingMode` | Notes                            |
| ------------------------------- | ------------- | -------------------------------- |
| Editable field user can modify  | `TWO_WAY`     | Changes flow both to/from the BO |
| Display-only field              | `ONE_WAY`     | BO → UI only; no write-back      |
| Static value (set once on load) | `ONE_TIME`    | Evaluated once; no live updates  |

**Rule:** `disabled="true"` controls should use `ONE_WAY`, not `TWO_WAY` — setting `TWO_WAY` on a disabled control is misleading but not a build error.

---

## Validation Message Display

When a BO property has a validation (from `.validationmessages.xml`), the framework automatically
shows an inline error beneath the control when the property fails validation. No additional UI
elements are needed — just ensure the control's `<Binding target="Value" ...>` uses `TWO_WAY`.

---

## Quick Reference: Control Selection

| Use case               | Control                                             |
| ---------------------- | --------------------------------------------------- |
| Short text input       | `InputArea`                                         |
| Long text / notes      | `InputAreaMultiLine`                                |
| Date selection         | `DatePickerField`                                   |
| Time selection         | `TimePickerField`                                   |
| Date + time together   | `Merger` with `DatePickerField` + `TimePickerField` |
| Picklist / dropdown    | `SelectionBox` with `toggleId`                      |
| Foreign key display    | `Lookup`                                            |
| Numeric with increment | `Stepper`                                           |
| Boolean toggle         | `CheckBoxField`                                     |
