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

# Data Binding & Context

> Bind data form components to extracted document data in Kodexa using context variables, expressions, and scoped data for multi-instance documents.

Data form components display values that originate from a document's extracted data -- the data objects and attributes produced by the taxonomy and extraction pipeline. At render time, the form renderer assembles these into a `DataContextV2` object and injects it via Vue's `provide`/`inject` mechanism so every component in the tree can access it as `ctx`.

## Context Variables

Binding expressions receive a `ctx` object with the following properties:

| Variable             | Type                     | Description                                                                                                   |
| -------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `ctx.dataObjects`    | `any[]`                  | All data objects in the current scope                                                                         |
| `ctx.$item`          | `any`                    | Current item when inside a `for` loop                                                                         |
| `ctx.$index`         | `number`                 | Current index when inside a `for` loop                                                                        |
| `ctx.$parent`        | `DataContextV2`          | Parent data context (for nested scopes such as `groupTaxon`)                                                  |
| `ctx.$root`          | `DataContextV2`          | Root data context, always the top-level context                                                               |
| `ctx.tagMetadataMap` | `Map<string, any>`       | Taxonomy metadata definitions keyed by tag path                                                               |
| `ctx.formValues`     | `Record<string, string>` | Shared record for cross-field value exchange                                                                  |
| `ctx.$bridgeResult`  | `any`                    | Service bridge response (only inside `v2:serviceBridgeView`, see [Bridge API](/guides/data-forms/bridge-api)) |
| `ctx.$bridgeLoading` | `boolean`                | `true` while a bridge request is in flight                                                                    |
| `ctx.$bridgeError`   | `string`                 | Error message if the bridge request failed                                                                    |

The full TypeScript interface:

```typescript theme={null}
interface DataContextV2 {
  dataObjects?: any[];
  $item?: any;
  $index?: number;
  $parent?: DataContextV2;
  $root?: DataContextV2;
  tagMetadataMap?: Map<string, any>;
  formValues?: Record<string, string>;
  [key: string]: any;
}
```

## Props vs Bindings

Every `UINode` can set values on its component through two mechanisms:

* **props** -- static values set at definition time. They do not change unless the form definition itself changes.
* **bindings** -- JavaScript expressions evaluated against `ctx` at render time. They re-evaluate automatically whenever the underlying data context changes.

When both `props` and `bindings` define the same key, the binding result takes precedence.

```json theme={null}
{
  "component": "card:label",
  "props": {
    "label": "Invoice"
  }
}
```

```json theme={null}
{
  "component": "card:label",
  "bindings": {
    "label": "ctx.dataObjects[0]?.attributes?.find(a => a.path === 'invoice/vendor')?.value || 'Untitled'"
  }
}
```

The first example always displays "Invoice". The second evaluates against live data and updates when the data objects change. See the [V2 Data Binding](/guides/data-forms/data-binding) guide for full expression syntax and the reactivity model.

## Tag Metadata

Components such as `v2:attributeEditor` use a `tagPath` prop to look up the corresponding taxonomy definition from `ctx.tagMetadataMap`. The metadata tells the component the attribute's data type (string, number, date, `SELECTION`), the available options for selection fields, the display label, and any validation or formatting rules defined in the taxonomy. This removes the need to duplicate type information in the form definition itself.

## Cross-Field Linking with valueFrom

The `valueFrom` prop on `v2:attributeEditor` displays a value sourced from a different attribute instead of its own:

* Set `valueFrom` to the tag path of the source attribute.
* The field becomes read-only automatically.
* The renderer checks `ctx.formValues` first, then falls back to searching `ctx.dataObjects` for a matching attribute path.

This is useful for showing a computed or linked value -- for example, displaying a total calculated elsewhere, or mirroring a value from a related data object.

```json theme={null}
{
  "component": "v2:attributeEditor",
  "props": {
    "tagPath": "invoice/computedTotal",
    "label": "Computed Total",
    "valueFrom": "invoice/lineItemSum"
  }
}
```

Here the editor at `invoice/computedTotal` displays the value from `invoice/lineItemSum` and prevents direct editing.

## Scoped Contexts with groupTaxon

When a `v2:panel` sets the `groupTaxon` prop, it scopes the data context for its children:

1. The panel filters `ctx.dataObjects` for objects whose `path` matches the `groupTaxon` value.
2. If multiple matching objects exist, the panel renders a tab for each instance.
3. Children receive a scoped `DataContextV2` containing only the active data object and all of its descendants (collected recursively by `parentId`).
4. Nested `groupTaxon` panels work within the already-scoped parent context, enabling hierarchies such as line items within a shipment.

```json theme={null}
{
  "component": "v2:panel",
  "props": {
    "title": "Shipments",
    "groupTaxon": "shipments"
  },
  "children": [
    {
      "component": "v2:attributeEditor",
      "props": {
        "tagPath": "shipments/trackingNumber",
        "label": "Tracking Number"
      }
    },
    {
      "component": "v2:panel",
      "props": {
        "title": "Line Items",
        "groupTaxon": "shipments/lineItems"
      },
      "children": [
        {
          "component": "v2:attributeEditor",
          "props": {
            "tagPath": "shipments/lineItems/description",
            "label": "Description"
          }
        }
      ]
    }
  ]
}
```

If a document contains three shipment data objects, the outer panel renders three tabs. Selecting a tab scopes all child components -- including the nested line items panel -- to that shipment's data. The inner panel then further scopes to the line items belonging to the selected shipment.

## Next Steps

<CardGroup cols={2}>
  <Card title="Layout Components" icon="table-columns" href="/guides/data-forms/layout-components">
    Panels, tabs, rows, columns, and alerts
  </Card>

  <Card title="Data Components" icon="pen-to-square" href="/guides/data-forms/data-components">
    Attribute editors, tables, grids, and more
  </Card>

  <Card title="Extraction" icon="wand-magic-sparkles" href="/guides/data-forms/extraction">
    Direct extract and AI-powered data extraction
  </Card>

  <Card title="Events & Scripting" icon="code" href="/guides/data-forms/scripting">
    Event handlers, QuickJS runtime, and document API
  </Card>
</CardGroup>
