Appearance
A searchable related-record lookup field
When you need this
Any form field whose value is another entity's id — category_id, equipment_id, employee_id. Use a core.lookup block, never a plain text or number input that makes the user type a raw id. (An entire module built by AI agents once shipped every FK as a bare number input because this pattern was undiscoverable.)
The three files
1. A Data View producing { value, label }
metadata/data_view/oeq-category-select-options-view.json (real file) — selects t.id AS value and a concatenated label. The output columns must be named value and label.
2. A search Data Service over that view
metadata/data_service/oeq-category-search.json (real file):
json
{
"name": "oeq-category-search",
"definition": {
"operation": "search",
"source": { "kind": "dataView", "dataViewName": "oeq-category-select-options-view" },
"filters": [ { "field": "t.category_name", "operator": "contains", "value": "${param.search}" } ],
"parameters": [ { "name": "search", "type": "string" } ]
}
}3. The core.lookup block on the page
json
{
"blockType": "core.lookup",
"properties": {
"value": { "source": "binding", "binding": { "scope": "page", "key": "formCategoryId" } },
"recordType": { "source": "static", "value": "OeqCategory" },
"optionsSourceKey": { "source": "static", "value": "oeq-category-search" }
},
"events": { "committed": { "source": "action-chain", "actions": [
{ "id": "a0", "order": 0, "type": "setValue",
"config": { "field": "page.formCategoryId", "value": "${event.new}" } }
] } }
}The rules
optionsSourceKey= thenameof thesearchData Service. This is the real wiring.recordType= a documentation-only label; it doesn't route anything.committedfires withevent.new= the picked record's id. Notevent.value, not the label.- If the target entity has no search-shaped Data Service yet, build files 1 and 2 first — don't fall back to a text input.
- For a small, static option set,
core.selectwith inlineoptionsis simpler and needs none of this.