> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.itential.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.itential.com/_mcp/server.

# Use field dependencies in JSON Forms

> How to use field dependencies to make one form field drive the options of another, with examples for cascading dropdowns and constrained searches.

A field dependency links one form field's value to the API request of another field. When the source field changes, the dependent field automatically re-fetches its options using the new value as a parameter. This lets you build forms where one selection meaningfully constrains or filters what the next field shows.

A common pattern is a cascading dropdown: a first dropdown selects an entity such as a device, and a second dropdown automatically populates with data specific to that entity such as that device's interfaces. Another pattern is a constrained search: a number input controls a `maxResults` parameter, so the form operator directly determines how many results a dropdown retrieves.

Without field dependencies, you would need a separate form submission and page reload to achieve the same effect—or hardcode parameters that the form operator can never change.

Field dependencies are configured on the dependent field's dynamic dropdown, under **Variables (Field Dependency)**. The source field is referenced by its JSON schema path (for example, `/device`). When using GET requests, the dependency replaces a route parameter. When using POST requests, it replaces a property in the request body.

The following examples demonstrate both patterns.

## Example 1: Retrieve device interfaces (GET request)

A Device dropdown populates from Configuration Manager. Selecting a device causes an Interface dropdown to fetch and display only that device's interfaces (GET request with a route parameter dependency).

### Step 1: Build the form structure

#### Create a JSON Form

In JSON Forms, create a new form.

#### Add two dropdown elements

Drag two **Dropdown** elements onto the canvas.

#### Label the dropdowns

Hover over the **…** menu on each dropdown and click the gear icon. In the **Configure** dialog, set the **Label** of the first dropdown to **Device** and the second to **Interface**.

![](/_fern-img/728a8242dcc6afb1539ca522feb796db9bcdebec4c819103e105dc8e290de04e.webp)

#### Save

Click **Save**.

### Step 2: Configure dynamic data binding for the Device dropdown

#### Open Configure

Hover over the **Device** dropdown and click the gear icon.

#### Add dynamic data binding

Click **+ Options** and select **Dynamic**. The **Dynamic Data Binding** editor opens.

#### Set the request configuration

Enter the following under **Request Configuration**:

```
Method:    POST
Base URL:  /configuration_manager
API Route: /devices
```

#### Set the request body

Enter the following in the **Request Body** editor:

```json
{
  "options": {
    "limit": 10000,
    "start": 0,
    "sort": [
      {
        "name": 1,
        "address": -1,
        "port": 1
      }
    ]
  }
}
```

#### Generate the response body

Click **Make API Call**.

![](/_fern-img/11842066375eab0f2df9b9489df3e50a2e60f708012a99aaa2421c4eafd49305.webp)

#### Configure data mapping

Under **Data Mapping**, select **Source-To-Target** and enter:

```
Source Property: /list
Property Key:    /name
```

Click **Query Data** to preview the list of discoverable devices.

![](/_fern-img/3b9de1ade54185ffea6cbc2bbe0230a3a7db937760a175be48d46ed429b30f26.webp)

#### Save

Click **Back**, then click **Save**.

### Step 3: Configure field dependencies for the Interface dropdown

#### Set the request configuration

Enter the following under **Request Configuration**:

```
Method:    GET
Base URL:  /configuration_manager
API Route: /devices/:name/configuration
```

#### Set the device name parameter

In the **Define Parameters** name field, enter an active device name from Configuration Manager.

#### Generate the device configuration

Click **Make API Call** to retrieve the device configuration in the **Response Body**.

#### Configure data mapping

Under **Data Mapping**, select **JSON Transformation** and enter the "Transform Device Config" [JST file](#json-transformation-file-for-device-config) provided below. Click **Run Transformation**. The **Target Data Preview** displays the interface name.

#### Set the field dependency

Under **Variables (Field Dependency)**, select **Form Reference** and enter the Device field reference:

```
/device
```

![](/_fern-img/4a816cfd7eb13b215c846ecfb03a73a0f3a132f66fca291c441ed711d7bc8ec9.webp)

#### Save

Click **Back**, then click **Save**.

### Step 4: Validate the form

#### Open the form

Go to **Studio > JSON Forms**, expand the **JSON Forms** menu in the left nav, and select the form.

#### Preview the form

Click the eye icon to open **Preview Form**. Select a device from the **Device** dropdown. The **Interface** dropdown populates with interfaces from that device's configuration.

#### Inspect the schema

Click **Show Form Data** to display the JSON schema. Click **Close** to return to the preview.

![](/_fern-img/f7ec2058d058eb46a05b01001bca7470ed4a14c47b1f27a81014ee9f7ed4b766.webp)

Data in **Preview Form** comes from a live device and may take a few seconds to appear depending on device configuration size and network conditions.

### JSON transformation file for device config

Copy the JSON below into a `.txt` file and save it as `Transform Device Config.jst.json`. Then [import the file](/itential-platform/studio/json-forms/create-manage#import-forms) into your transformation library in Studio.

```json
{
  "name": "Transform Device Config",
  "incoming": [
    {
      "$id": "config",
      "type": "string"
    }
  ],
  "outgoing": [
    {
      "$id": "out",
      "type": "array"
    }
  ],
  "steps": [
    {
      "id": 2,
      "type": "assign",
      "from": {
        "location": "incoming",
        "name": "config",
        "ptr": ""
      },
      "to": {
        "location": "method",
        "name": 1,
        "ptr": "/args/0/value"
      },
      "context": "#"
    },
    {
      "id": 1,
      "type": "method",
      "library": "String",
      "method": "split",
      "args": [
        null,
        "\n",
        null
      ],
      "view": {
        "row": 1,
        "col": 1
      },
      "context": "#"
    },
    {
      "id": 4,
      "type": "assign",
      "from": {
        "location": "method",
        "name": 1,
        "ptr": "/return"
      },
      "to": {
        "location": "method",
        "name": 3,
        "ptr": "/args/0/value"
      },
      "context": "#"
    },
    {
      "id": 3,
      "type": "method",
      "library": "Array",
      "method": "filter",
      "args": [
        null,
        "ƒ_query_1"
      ],
      "view": {
        "row": 2,
        "col": 2
      },
      "context": "#"
    },
    {
      "id": 6,
      "type": "method",
      "library": "Array",
      "method": "map",
      "args": [
        null,
        "ƒ_map_1"
      ],
      "view": {
        "row": 1,
        "col": 3
      },
      "context": "#"
    },
    {
      "id": 7,
      "type": "assign",
      "from": {
        "location": "method",
        "name": 3,
        "ptr": "/return"
      },
      "to": {
        "location": "method",
        "name": 6,
        "ptr": "/args/0/value"
      },
      "context": "#"
    },
    {
      "id": 8,
      "type": "assign",
      "from": {
        "location": "method",
        "name": 6,
        "ptr": "/return"
      },
      "to": {
        "location": "outgoing",
        "name": "out",
        "ptr": ""
      },
      "context": "#"
    }
  ],
  "functions": [
    {
      "name": "ƒ_query_1",
      "incoming": [
        { "$id": "element", "type": ["array","boolean","number","integer","string","object","null"] },
        { "title": "index", "type": "number", "optional": true, "$id": "index" },
        { "type": "array", "$id": "array", "optional": true },
        { "$id": "thisArg", "type": "object", "properties": {}, "isContext": true, "isThis": true, "isIndexed": true }
      ],
      "outgoing": [
        { "title": "return", "type": "boolean", "$id": "return" }
      ],
      "steps": [
        { "id": 5, "type": "assign", "from": { "location": "incoming", "name": "element", "ptr": "" }, "to": { "location": "method", "name": 4, "ptr": "/args/0/value" }, "context": "#" },
        { "id": 4, "type": "method", "library": "String", "method": "trim", "args": [null], "view": { "row": 2, "col": 1 }, "context": "#" },
        { "id": 6, "type": "assign", "from": { "location": "method", "name": 4, "ptr": "/return" }, "to": { "location": "method", "name": 1, "ptr": "/args/0/value" }, "context": "#" },
        { "id": 1, "type": "method", "library": "String", "method": "startsWith", "args": [null, "interface", null], "view": { "row": 1, "col": 1 }, "context": "#" },
        { "id": 3, "type": "assign", "from": { "location": "method", "name": 1, "ptr": "/return" }, "to": { "location": "outgoing", "name": "return", "ptr": "" }, "context": "#" }
      ],
      "functions": [],
      "view": { "col": 1, "row": 3 },
      "id": "ƒ_query_1",
      "comments": []
    },
    {
      "name": "ƒ_map_1",
      "incoming": [
        { "$id": "currentValue", "type": ["array","boolean","number","integer","string","object","null"] },
        { "title": "index", "type": "number", "optional": true, "$id": "index" },
        { "type": "array", "$id": "array", "optional": true },
        { "$id": "thisArg", "type": "object", "properties": {}, "isContext": true, "isThis": true, "isIndexed": true }
      ],
      "outgoing": [
        { "title": "newValue", "type": ["array","boolean","number","integer","string","object","null"], "editable": true, "$id": "newValue" }
      ],
      "steps": [
        { "id": 1, "type": "method", "library": "String", "method": "trim", "args": [null], "view": { "row": 1, "col": 1 }, "context": "#" },
        { "id": 2, "type": "assign", "from": { "location": "incoming", "name": "currentValue", "ptr": "" }, "to": { "location": "method", "name": 1, "ptr": "/args/0/value" }, "context": "#" },
        { "id": 3, "type": "assign", "from": { "location": "method", "name": 1, "ptr": "/return" }, "to": { "location": "outgoing", "name": "newValue", "ptr": "" }, "context": "#" }
      ],
      "functions": [],
      "view": { "col": 1, "row": 3 },
      "id": "ƒ_map_1",
      "comments": []
    }
  ],
  "view": { "col": 3, "row": 5 },
  "_id": "6472c5cb363dd75d098b8d0d",
  "description": "",
  "comments": [],
  "version": "3.23.3-2022.1.14"
}
```

## Example 2: Limit a form search (POST request)

A Form Limit number input controls the `maxResults` parameter of a Forms dropdown search (POST request with a request body dependency).

A **Forms** dropdown makes a POST request to `/formbuilder/forms/search`. The request body property `/options/maxResults` limits how many forms are returned. A **Form Limit** number input is added to the form and set as the field dependency for `/options/maxResults`, so the form operator controls the result cap directly.

### Step 1: Build the form structure

#### Add elements

Drag a number input and a dropdown onto a new form.

#### Label the number input

Hover over the number input and click the gear icon. Set the **Label** to **Form Limit** and click **Save**.

#### Label the dropdown

Open the dropdown's **Configure** dialog and set the **Label** to **Forms**. Leave the dialog open for the next step.

![](/_fern-img/9c9dbe7b3f5d91ef010afe4ca45b0ec600a5fa3cfe18b05c33e299bcb52919ae.webp)

### Step 2: Configure dynamic data binding for the Forms dropdown

#### Add dynamic data binding

Click **+ Options** and select **Dynamic**. The **Dynamic Data Binding** options appear.

#### Set the request configuration

Enter the following under **Request Configuration**:

```
Method:    POST
Base URL:  /formbuilder
API Route: /forms/search
```

#### Set the request body

Enter the following in the **Request Body**:

```json
{
  "options": {
    "maxResults": 25,
    "startAt": 0,
    "sort": { "name": 1 },
    "fields": ["name","children","elements","createdBy","created","lastUpdatedBy","lastUpdated","tags"],
    "filter": { "name": { "$regex": "(e)", "$options": "i" } },
    "expand": ["createdBy","lastUpdatedBy"]
  }
}
```

#### Generate the response body

Click **Make API Call**. A list of forms appears in the **Response Body**.

![](/_fern-img/133c6fe0ee9e4fecc956df457f10799d0b887eb0761084e0188afa91d6d0d24b.webp)

#### Configure data mapping

Under **Data Mapping**, click **Source-To-Target** and enter:

```
Source Property: /results
Property Key:    /name
```

Click **Query Data** to preview the form names.

![](/_fern-img/c5355abf15a4619eb1334b379549654b0f1cd726b7a9c89502de90d3f5becfd3.webp)

#### Set the field dependency

Under **Variables (Field Dependency)**, click **+ Variable** and enter:

```
Request Body Pointer: /options/maxResults
Schema Reference:     /formLimit
```

Click **Back**, then click **Save**.

![](/_fern-img/4e94c0f104b9fc300cd6ac4e3108aff3bc1e063097933e309f63456aedd6ef97.webp)

### Step 3: Test the form

#### Preview the form

Click the eye icon to open a live preview.

#### Verify behavior

Confirm that changing the **Form Limit** value caps the number of options in the **Forms** dropdown.

## API calls and dynamic data binding

Adapter calls do not always map directly to the underlying system-level API call. This mainly affects system-level `GET` calls.

### GET calls translated to POST

All system-level `GET` calls with defined query parameters in the adapter's OpenAPI/Swagger specification are translated to adapter `POST` calls.

For example, consider the F5 BIG-IP API:

![](/_fern-img/02ca8b88f202771ec7dc2fd0f0e3a181f1a6c92be077d8326b8d2c088e009061.webp)

At the system level this is a `GET` call, but as an adapter call it must be a `POST` request with the listed object keys in the request body. Without those parameters, the adapter call returns no output. The keys can be provided as empty strings:

```json
{ "select": "", "filter": "" }
```

### Find required parameters

For system-level `GET` calls that must be translated to `POST`, find the required parameters at:

```
https://<IAP_IP>:<PORT>/rest-api
```

If an adapter `GET` call is not listed there, confirm that:

* An adapter `POST` call for that system does not already exist.
* The developer has authorization to make the adapter call.