Skip to content

Trees, timelines, rich content, and AI controls

Client keyword reference / Trees, timelines, rich content, and AI controls

IFS Cloud 26R1 · Documentation-based examples · Not compiled or executed in IFS.

Advanced controls still depend on ordinary typed data and explicit relationships. Establish a small known dataset and a simple page before adding the presentation. The snippets below are separate examples, not one file to concatenate.

Expose DemoAssetSet of type DemoAsset with AssetId, Name, and a Children array to the same type. Define AssetSelector and an AssetDetails page first.

tree TrainingAssets using DemoAssetSet {
label = "Training asset structure";
selector AssetSelector;
rootnode {
label = "${Name}";
navigate { page AssetDetails { filter(AssetId, AssetId); } }
connections { node ChildAsset(Children); }
}
node ChildAsset for DemoAsset {
label = "${Name}";
navigate { page AssetDetails { filter(AssetId, AssetId); } }
connections { node ChildAsset(Children); }
}
}

Connect the tree through the supported navigator entry for your generated model. Test root → child → grandchild, a leaf, and a denied child. Ensure the service prevents cycles and duplicate keys. Navigation mappings must include all destination keys. Optional navicontexts selects alternative navigation destinations; it does not change the underlying hierarchy or permission model.

With the same keyed asset model, define a diagram and add treediagram TrainingAssetDiagram; to the appropriate bound page:

treediagram TrainingAssetDiagram {
label = "Training asset relationships";
node AssetNode for DemoAsset {
zoomlevels {
small { field AssetId; }
large { field AssetId; field Name; }
}
connections {
node AssetNode(Children) {
connectedFrom = AssetId;
connectedTo = ParentAssetId;
}
}
}
}

Expose ParentAssetId too and verify each connection against a simple parent/child table. A duplicate label is acceptable; duplicate identity is not. Test small and large zoom views, disconnected roots, and cycles. A nestednode can switch to another node type but requires that node’s own definition and correctly typed relationship.

For an audit-style display, expose event rows with OccurredAt, Summary, and Detail:

timeline RequestHistory for DemoRequestEvent {
date OccurredAt;
header Summary;
field Detail;
}

Insert timeline RequestHistory using DemoRequestEventSet; in a page and compare three deliberately out-of-order timestamps with the rendered order. Check equal timestamps and timezone display. Do not fabricate audit events in the client.

For a staged workflow, expose DemoStage with Description and SelectedStage. Define processviewer ReviewStages for DemoStage { label = "${Description}"; activestage = "${SelectedStage}"; }. Insert it through the parent’s Stages array and bind a compatible stage group and action list inside the insertion: processviewer ReviewStages(Stages) { group StageDetails bind ReviewStages; list StageActions(Actions) bind ReviewStages; }. Verify switching stages changes both detail controls. The viewer does not execute the workflow’s business transitions.

Map the address parts to actual projection attributes inside a group:

addressfield {
label = "Visit address";
address1 Street;
city CityName;
zipcode PostalCode;
country CountryName;
countrycode CountryCode;
}
field AssignedPerson {
contactwidget {
enabled = [true];
source = Person;
key = AssignedPerson;
}
}

Add address2, county, and state only when your contract supplies them. Check two countries with different formats and a missing country code. The contact key must identify the configured Person source; a display name is not a stable identity. Confirm the preview cannot expose a person the user is not authorized to see.

In a supported page/group/card container, provide contextual help with:

markdowntext {
text = "**Before review:** verify the request ID and site.";
}

For a card with a compatible image attribute, use imagefield { imagedata PhotoData; label = "Training asset photo"; }. Check a valid image, no image, and a restricted record. This is distinct from the page-level Image Viewer documented by IFS; that reference currently leaves its implementation sections incomplete, so no invented Image Viewer syntax is offered here.

A signature capture in a group uses signature SignatureData { label = "Training acknowledgment"; size = Large; } with the required compatible image/binary attribute and save contract. Draw, clear, save, and reload a disposable signature. Capture alone does not establish signer identity or implement a legally valid signing workflow.

Expose a readable JSON attribute DiagnosticJson on DemoRequest, then declare and insert the viewer:

jsonviewer TrainingDiagnostic for DemoRequest {
label = "Training diagnostic data";
attribute = DiagnosticJson;
}
// Inside the bound page:
jsonviewer TrainingDiagnostic;

Alternatively set function = GetTrainingDiagnostic(RequestId); instead of attribute, backed by a correctly typed projection function returning LongText or Stream as documented. Test valid nested JSON, empty data, invalid JSON, and a bounded large payload. Remove credentials and personal data from diagnostic output on the server; making a viewer read-only does not make its contents safe to expose.

AI functionality requires the appropriate configured service, permissions, and action contracts. Begin with a permitted training field:

field Notes {
multiline = true;
smarteditor { enabled = [true]; }
}

A compatible command can declare aisettings { indicateai = [true]; }; a dialog can additionally include disclaimer { text = "Review generated suggestions before using them."; } inside that block. These declarations label the UI; they do not configure a model or grant it access.

For a project-defined generator, a smart command DraftTrainingSummary { label = "Draft summary"; execute { call GenerateTrainingSummary(RequestId); } } requires the corresponding action and supported smart-editor context. Structured input uses a declared smartinputs block for a projection structure. A separate copilot prompt can be defined with copilotprompt ReviewTrainingPrompt { description = "Suggest review questions"; prompttext = "Suggest checks for training request ${RequestId}."; } and invoked with copilotprompt ReviewTrainingPrompt; in an execute block.

Test unavailable AI, rejected service access, cancellation, and a generated suggestion that is wrong. Require user review before persistence. Do not pass confidential record content to a provider merely because the control is enabled.

Use the build and acceptance checklist before delivering a change.