Skip to content

Build editors and resolve object endpoints

Editors collect fields and submit an object, link, or method request. They are embedded by actions and by editing variants; an editor is not a standalone panel variant.

Start by deciding what is being changed and where every participating object comes from. Then choose presentation mode and fields. This order prevents a good-looking form from submitting the wrong object or relationship GUID.

Choose the mutation model

TaskentityType / overrideRequired input
Create or update an objectentityType.object.metaTypeNameMetaType and fields
Create a linkentityType.linksource, target, and normally linkName
Create an object and link itboth object and linkone endpoint usually uses getFromCreatedObject
Invoke a MetaMethodrunMethodparent, method, optional objects and params

runMethod redirects submission to /MetaMethods/Run; it is not an additional post-save hook. Preconfigured objects/params and form values are merged by the method flow.

Presentation modes

ModeBehaviorUse when
modalOpens a dialog and waits for user inputnormal create/edit flows
panelUses a panel-owned editor surfacethe consuming variant explicitly supports it
direct-requestApplies defaults and submits without a formevery required value and endpoint is deterministic

modal is the practical default in current action flows, but mode is required in the EditorType contract. Do not use direct-request when the user must choose an endpoint or provide a value.

Fields, tabs, and rows

Use either top-level fields or tabs. A tab needs a stable id, localized title, and its own fields. A { "layout": "row", "fields": [...] } group places compact controls together.

Every leaf field requires attribute. Important field behavior:

  • editAttribute submits to a different path than the displayed attribute;
  • readonly displays but does not provide editable input;
  • hidden excludes the field from the visible/validated shared flow;
  • type, label, listOfValue, comment, regEx, and defaultValue override backend metadata when explicitly set;
  • propertyAsId and selectPanel configure object selection.

See metadata precedence and typed controls.

A LinkEndpoint resolves one object selector at action time.

EndpointResolves fromTypical use
objectIdfixed ObjectSelectorknown configuration object
getFromItemcurrent Table/Tree itemrow action
getFromCreatedObjectobject created earlier in the same flowcreate object, then link it
getSelectedObjectForPanelIdlast selection in a panelcross-panel action when panel identity is stable
getSelectedObjectForEventIdevent registry selectiondependent request/editor
getFromActionIdaction result contextchained action flow
selectPaneluser choice in an inline modal panelendpoint cannot be known in advance

For a linked selector, idSource decides which GUID is extracted:

  • omitted or "linkedObject": the target object's GUID;
  • "link": the relationship entity's GUID.

Use "link" for deleting or updating the relationship. Use the default for object CRUD and methods that accept the linked object.

Endpoint support is consumer-specific. The union type documents possible sources, but a particular create, update, runMethod, reload, or event path may support only a subset. Verify the action guide before combining endpoint forms.

Minimal object editor

json
{
  "mode": "modal",
  "entityType": {
    "object": { "metaTypeName": "ProductionOrder" }
  },
  "fields": [
    { "attribute": "name", "label": "Name" }
  ]
}

The ProductionOrder MetaType must exist. The form inherits its type metadata when the metadata endpoint provides it.

Use this editor on a row action for a parent object. The newly created operation becomes the source of the link; the clicked order is the target.

json
{
  "mode": "modal",
  "header": {
    "title": { "en": "Create operation", "ru": "Создать операцию" },
    "propertyAsId": "code"
  },
  "entityType": {
    "object": {
      "metaTypeName": "Operation"
    },
    "link": {
      "linkName": "OrderOperation",
      "source": { "getFromCreatedObject": true },
      "target": { "getFromItem": true }
    }
  },
  "fields": [
    {
      "attribute": "code",
      "type": "String",
      "label": { "en": "Code", "ru": "Код" },
      "regEx": "^OP-[0-9]+$"
    },
    {
      "attribute": "duration",
      "type": "Integer",
      "label": { "en": "Duration, min", "ru": "Длительность, мин" }
    },
    {
      "attribute": "link.sequence",
      "type": "Integer",
      "label": { "en": "Sequence", "ru": "Порядок" }
    }
  ]
}

link.sequence belongs to link metadata/payload; the other fields belong to the new object.

Choose a target with a panel

json
{
  "entityType": {
    "link": {
      "linkName": "OrderProduct",
      "source": { "getFromItem": true },
      "target": {
        "selectPanel": {
          "label": { "en": "Choose product", "ru": "Выберите изделие" },
          "width": "48rem",
          "height": "28rem",
          "panel": {
            "id": "product-picker",
            "type": "table",
            "request": { "metaTypeName": "Product" },
            "pagination": { "rowsPerPage": [10] },
            "columns": [
              { "attribute": "code", "label": "Code" },
              { "attribute": "name", "label": "Name" }
            ]
          }
        }
      }
    }
  }
}

The selection panel needs a complete request and a selectable variant. Its ID must not collide with the containing application.

Method-backed editor

json
{
  "mode": "modal",
  "runMethod": {
    "parent": "ProductionOrder",
    "method": "release",
    "objects": [
      { "getSelectedObjectForEventId": "order-selected" }
    ],
    "params": {
      "source": "configurator"
    }
  },
  "fields": [
    {
      "attribute": "comment",
      "type": "Text",
      "label": "Release comment"
    }
  ]
}

The MetaMethod defines the real object and parameter contract. Configurator JSON does not validate its name or payload.

Open modal, inline, typed, and object-selection editor forms Open create, update, selected-object detail, and linked-read flows

Defaults, precedence, and submission interactions

  1. The action or variant supplies its current item, selection, and action ID.
  2. The editor resolves object/link endpoints for that consumer.
  3. Existing-object flows load detail projections from attribute and editAttribute paths.
  4. Explicit field metadata overrides loaded attribute metadata.
  5. Loaded values win over defaults; defaults fill only undefined fields.
  6. Shared validation checks regex and JSON, then the consumer submits.
  7. Follow-up response actions or reload actions refresh dependent surfaces.

For plain data, blank Guid and Object values normalize to null. This is a submission boundary, not a general “all empty strings become null” rule.

Limits and current drift

  • required is not enforced by the shared validator.
  • Editor mode support varies by consumer; a type declaration does not prove every action renders panel mode.
  • withLinkedAttribute is declared for object entity types, but public runtime semantics are not sufficiently verified for a recommended journey.
  • Endpoint variants are not universally supported by every action processor.
  • Direct Link create/update/by-GUID fixture handlers exist, but the checked-in interactive Object API demo does not exercise them. Do not treat that route as runnable proof of direct Link mutations.
  • Method names, parameter schemas, and permission rules belong to the backend contract.

Exact property reference

Presentation and structure:

Editor fields:

Object, link, and method targets:

LinkEndpoint target sources:

Next tasks