kodexa.* namespace, where each sub-namespace corresponds to a capability gated by the form’s bridge permissions.
Bridge Permissions
Thebridge property on a data form configures what scripts are allowed to do. The permissions array lists capability gates — a script that attempts to call a method without the required permission will receive a Permission denied error.
Additional bridge configuration:
apiBaseUrl— Base URL forkodexa.httpandkodexa.serviceBridgecalls. Defaults to"/api".maxExecutionMs— Script execution timeout in milliseconds. Defaults to1000.
kodexa.data
Requiresdata:read. Methods that modify data also require data:write, and the two focused-field methods that only move focus or reveal values require navigation — each method’s gate is listed in the table.
Focused-field methods
The last six methods take no arguments and act on whichever field the reviewer currently has focused, so one form-declared shortcut works across every field in the form:clearFocusedValue()blanks the field’s value while keeping the attribute record.deleteFocusedValue()removes the attribute entirely. Both leave the field looking blank, but an absent attribute is not an empty one — the distinction can matter for export and validation.addDataGroup()adds a sibling row after the focused field’s data group.deleteDataGroup()deletes the data group the focused field belongs to.blurField()drops focus from the field without changing any data.showInDocument()reveals the focused field’s value in the document viewer.
data:write; blurField and showInDocument need only navigation, so a read-only form can still move focus and reveal values.
These methods exist to back data-entry keyboard shortcuts. Bind them declaratively as form shortcuts entries (see Keyboard Shortcuts) whose scripts call, for example, kodexa.data.clearFocusedValue().
kodexa.navigation
Requiresnavigation. Spatial-viewer methods route to the document viewer for the form’s first document family by default; pass an explicit documentFamilyId when a form is bound to more than one document.
Note that
focusAttribute takes dataObjectUuid as the first parameter and attributePath as the second.
rotatePage behaves differently from the absolute setPage:
- Rotation is relative. Each call rotates by ±90° from the page’s current rotation — it is not an absolute angle. Calling
rotatePage("right")twice leaves the page at 180°; a followingrotatePage("left")returns it to 90°. - It affects only the current page. Rotating every page of the document remains a separate viewer menu action; the bridge method touches just the page the viewer is currently showing.
- It requires the
navigationpermission and accepts an optionaldocumentFamilyIdto target a specific open document when the form is bound to more than one. A per-document rotation does not bleed across documents.
direction (anything other than "left" or "right") or a missing viewer is a no-op — a warning is logged to the browser console and no error is thrown.
alt+R / alt+shift+R bindings are not hard-coded — they are authored declaratively as form shortcuts entries whose script calls kodexa.navigation.rotatePage(...):
rotate-page-right script calls kodexa.navigation.rotatePage("right") and rotate-page-left calls kodexa.navigation.rotatePage("left"), so a shortcuts: block round-trips through the data form schema.
Section and exception jumps
nextSection() and nextException() walk a reviewer through the form rather than the document:
nextSection()scrolls the form to the next visible section and focuses its first input. Sections are the form’s visiblev2:panelcomponents; each call advances one section, and after the last section the jump wraps back to the top of the form.nextException(documentFamilyId?)scrolls the form to the next open validation exception. The anchor is the field’s attribute editor when one is rendered; for an exception on a grid row, it is the grid containing the row. LikenextSection, it cycles back to the top after the last anchor. Pass the optionaldocumentFamilyIdto scope the exception scan to a specific open document when the form is bound to more than one.- Both return
falsewhen the window has nothing to act on — no form pane in the current window (for example a popped-out viewer tab), or, fornextException, no open exceptions. A warning is logged to the browser console and no error is thrown. Both require thenavigationpermission.
shortcuts entries to give reviewers keyboard-driven section-by-section or exception-by-exception review:
next-section script calls kodexa.navigation.nextSection() and next-exception calls kodexa.navigation.nextException().
kodexa.viewer
Requiresviewer. The viewer surface manipulates the spatial document viewport — its scroll and pan position, its zoom level, and whether the viewer is docked in the workspace or popped out into its own browser tab — rather than the page state. That separation is why it is a distinct permission from navigation.
scrolldirection is one of"up","down","left","right". Any other value is a no-op — a warning is logged to the browser console and no error is thrown."up"/"down"scroll the viewer vertically;"left"/"right"pan the zoom transform (the spatial image is CSS-transformed, so left/right movement pans rather than scrolls). Both feel like a small “arrow key” nudge, not a full-screen jump.zoomsteps one increment in or out."in"and"out"map to the toolbar’s zoom-in / zoom-out buttons — one call is one step. Any other value is a no-op with a browser-console warning and no error thrown.showRegionresets zoom and brings a region of the current page into view. The region is one of"top","middle", or"bottom"; any other value is a no-op with a browser-console warning. The region names are looser than they sound —"middle"scrolls to roughly a quarter down the page, matching long-standing viewer behavior.fitzooms so the page fills the viewport."width"fits the page to the viewport’s width,"height"to its height; any other value is a no-op with a browser-console warning.copySelectioncopies the current document selection to the clipboard. It deliberately stays out of the way while you are typing in a field — when focus is inside an input, the method does nothing, so a copy shortcut bound to it coexists with native copy in form fields.detachpops the viewer out into a new browser tab. This is the same action as the viewer’s “Open in new tab” button. It is only meaningful from the main window — calling it from inside the popped-out tab is a no-op (a warning is logged). If the pop-out tab is already open,detachfocuses that tab rather than opening a second one. It takes no arguments.dockreturns a popped-out viewer to the workspace. This mirrors the viewer’s “Dock back to workspace” button and works from either the main window or the popped-out tab. When no viewer is currently detached it is a no-op with a warning. It takes no arguments.scroll,zoom,showRegion,fit, andcopySelectioncan target one document. With no argument they act on the form’s default (first) document family; pass an optionaldocumentFamilyIdto target a specific open document. All five apply to the viewer whether it is docked in the workspace or popped out into its own tab.detachanddockalways act on the workspace’s pop-out viewer and take no target.- Requires the
viewerpermission. Calling anykodexa.viewermethod without"viewer"inbridge.permissionsthrows aPermission denied: viewererror.
shortcuts entries (see Keyboard Shortcuts); zoom, detach, and dock fit the "zoom" help-dialog group. The keys below are only examples chosen by the form author — there are no fixed hotkeys for these actions:
scriptRef points at a script that calls the matching method — for example detach-viewer calls kodexa.viewer.detach() and dock-viewer calls kodexa.viewer.dock().
kodexa.form
RequiresformState.
Form state is ephemeral — it persists for the lifetime of the form session but is not saved to the server. Use it for UI-only concerns like toggling visibility, tracking selection state, or passing values between scripts.
kodexa.document
Requiresdocument:read. The writable snapshot also requires data:write.
The
ScriptDocumentProxy exposes getAllDataObjects(), getDataObjectByUUID(uuid), and getDataObjectsByPath(path). Each returns ScriptDataObjectProxy instances with methods like getAttributes(), getAttribute(label), getChildren(), and getPath(). Writable proxies additionally support addAttribute(), addChild(), and setValue() on attributes.
This API is separate from loadDocument() available in inline or named scripts. kodexa.document provides Bridge API context tied to the current workspace session; loadDocument() is for standalone script execution.
kodexa.http
Requireshttp:get for GET requests, http:post for POST requests. Both are async.
Requests are sent to
apiBaseUrl + path. The base URL defaults to "/api" if not configured.
kodexa.serviceBridge
Requireshttp:post.
Service bridges are named proxy endpoints that connect the platform to external APIs with centralized authentication. The
ref is the bridge slug (e.g., "acme-logistics/carrier-lookup"), and endpoint is the endpoint name defined in the bridge YAML.
The bridge manages an X-Bridge-Context header for session caching. On the first call, no context header is sent; the server runs any configured initScript and returns context in the response header. Subsequent calls attach the cached context, skipping re-initialization. Context expires after a configurable TTL (default 3600 seconds).
kodexa.log
No permission required.
All log output is prefixed with
[DataFormV2] and routed to the browser console.
Service Bridges on Panels
In addition to imperativekodexa.serviceBridge.call() from scripts, panels support declarative service bridge integration through the serviceBridge prop on v2:panel. This allows a component to declare an external API dependency without writing script code.
ServiceBridgeConfig
ServiceBridgeResponseMapping
How It Works
When any attribute listed intriggerOn changes, the panel reads the current values from requestMapping, calls the service bridge endpoint, and maps the response back using responseMapping. This creates a reactive loop: user edits a field, the bridge fetches updated data, and dependent fields populate automatically.
v2:serviceBridgeView
A container component that calls a service bridge endpoint and makes the response available to its children through the data context. Unlike the panelserviceBridge prop (which maps responses back to attributes), v2:serviceBridgeView is designed for read-only display — rendering bridge responses as tables, markdown, labels, or any combination of child components.
How It Works
- The component resolves the bridge slug to an ID via the platform’s
/api/resolveendpoint. - It POSTs the
paramsto the bridge proxy endpoint (/api/service-bridges/{id}/proxy/{endpoint}). - If a
transformexpression is provided, the response is reshaped using JSONata. - The result is injected into a scoped
DataContextV2asctx.$bridgeResult, along withctx.$bridgeLoadingandctx.$bridgeError. - Children render using bindings that reference these context variables.
Props
Context Variables
Children ofv2:serviceBridgeView receive these additional context variables:
All existing context variables (
ctx.dataObjects, ctx.tagMetadataMap, etc.) remain available — the bridge context is additive.
Reactive Parameters
Whenparams is provided via bindings, the component re-calls the bridge whenever the bound values change. This creates a reactive chain: the user edits an attribute, the binding expression re-evaluates, new params are sent to the bridge, and children re-render with fresh data.
When referencing attributes in binding expressions, the
tag property is the leaf name (e.g., originZip), not the full taxonomy path (shipment/originZip). The full path is available as path on the attribute. Use a.tag === 'originZip' or a.path === 'shipment/originZip' depending on which you need.Example: Table from Bridge Response
Call a rate lookup endpoint, transform the response with JSONata, and render the results as a filterable AG Grid table:Example: Markdown Summary
Fetch a report from a bridge and render it as markdown:Example: Mixed Content
Combine multiple child components to render different parts of the bridge response:JSONata Transform Reference
Thetransform prop accepts any valid JSONata expression. Common patterns:
If the transform is omitted, the raw response is passed through as
ctx.$bridgeResult.
The JSONata transform runs client-side after the response is received. For large responses, consider using the bridge’s
postReplyScript to filter server-side before the data reaches the browser.