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

# Navigation

This document describes how to programmatically navigate to pages, fields, table/collection rows, and individual cells within a form using the `goto` API on `DocumentEditor`.

## Overview

The `goto` method enables programmatic navigation to specific locations within a form. This is useful for:

* Guiding users to required fields after validation
* Implementing custom navigation flows
* Deep linking to specific form sections
* Auto-scrolling to specific fields
* Opening a specific table or collection row in its row form (modal)
* Focusing a specific cell within a table or collection row

## Path-Based Navigation

Navigate using a slash-separated path string. Up to four segments are supported.

```swift theme={null}
// Navigate to a page
let status = editor.goto("page_123")

// Navigate to a field on a page (with auto-scroll)
let status = editor.goto("page_123/fieldPosition_456")

// Navigate to a table or collection row (optionally open row form)
let status = editor.goto("page_123/fieldPosition_456/row_789", gotoConfig: GotoConfig(open: true))

// Navigate to a specific cell in a table or collection row
let status = editor.goto("page_123/fieldPosition_456/row_789/column_012", gotoConfig: GotoConfig(open: true, focus: true))
```

| Path Format                               | Description                                                                                                                                                          |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `"pageId"`                                | Navigate to the top of the specified page                                                                                                                            |
| `"pageId/fieldPositionId"`                | Navigate to the page and automatically scroll to the field                                                                                                           |
| `"pageId/fieldPositionId/rowId"`          | Navigate to the page, scroll to the table/collection field, and select the row. Use `GotoConfig(open: true)` to also open the row form modal.                        |
| `"pageId/fieldPositionId/rowId/columnId"` | Navigate to the page, scroll to the table/collection field, select the row, and target a specific column/cell. Use `GotoConfig(focus: true)` to auto-focus the cell. |

<Warning>
  **Important:** Use `fieldPositionId` from `page.fieldPositions[]._id`, not `fieldId` from `document.fields[]._id`. Using the wrong ID will cause navigation to fail.
</Warning>

For row-level paths, the field must be a **table** or **collection** type. The `rowId` must match an existing row's ID in that field's value; otherwise `goto` returns `.failure`.

For column-level paths, the `columnId` must match an existing visible column in the field; otherwise `goto` returns `.failure` (but still navigates to the row).

## GotoConfig

Navigation behavior is configured via `GotoConfig`. Pass it as the second argument to `goto`.

```swift theme={null}
public struct GotoConfig {
    /// When true, automatically opens the row form modal for table/collection rows.
    public let open: Bool

    /// When true, triggers the onFocus callback for the target field or cell.
    public let focus: Bool

    public init(open: Bool = false, focus: Bool = false)
}
```

| Property | Default | Description                                                                                                                                     |
| -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `open`   | `false` | If the path targets a table/collection row, set to `true` to open that row's form in a modal after navigation.                                  |
| `focus`  | `false` | When `true`, triggers the SDK's `onFocus` event for the target field or cell. For text, number, and barcode cells this also opens the keyboard. |

Examples:

```swift theme={null}
// Navigate to a row and open its form for editing
let status = editor.goto("page_123/fieldPosition_456/row_789", gotoConfig: GotoConfig(open: true))

// Navigate to a field and trigger onFocus
let status = editor.goto("page_123/fieldPosition_456", gotoConfig: GotoConfig(focus: true))

// Navigate to a specific cell, open the row form, and focus the cell
let status = editor.goto("page_123/fieldPosition_456/row_789/column_012", gotoConfig: GotoConfig(open: true, focus: true))
```

If you omit `gotoConfig`, the default `GotoConfig()` is used (`open: false`, `focus: false`).

## NavigationStatus

The `goto` method returns a `NavigationStatus` indicating success or failure.

```swift theme={null}
let status = editor.goto("page_123/fieldPosition_456", gotoConfig: GotoConfig())

switch status {
case .success:
    // Navigation succeeded - target exists and is visible
    print("Successfully navigated to the field")
case .failure:
    // Navigation failed - target doesn't exist, is hidden, or unsupported
    print("Navigation failed")
}
```

| Response   | Description                                                                                                                              |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `.success` | The target exists, is supported, and is visible (and for row paths, the row exists; for column paths, the column exists and is visible). |
| `.failure` | The target does not exist, is hidden, or has an unsupported field type.                                                                  |

**Failure reasons include:**

* Page does not exist
* Page is hidden (due to conditional logic)
* Field position does not exist
* Field is hidden (due to conditional logic)
* For row-level paths: field is not a table/collection, or the row ID is not found in the field's value
* For column-level paths: the column ID does not exist or is hidden

When the page changes, the SDK emits page focus and page blur events. See [Event Handling](/ios/guides/event-handling#onfocus-event) for details.
