AI: JSON authoring rules
This page defines how an agent must construct NGX View Builder JSON.
Minimal skeleton
json
{
"settings": {
"language": "en",
"locale": "en-US",
"renderMode": "page"
},
"pages": [
{
"name": "page1",
"rows": [
{
"columns": [
{ "elementRef": "field1" }
]
}
]
}
],
"elements": {
"page1": {
"name": "page1",
"label": "Page 1",
"type": "page"
},
"field1": {
"name": "field1",
"label": "Field 1",
"type": "text"
}
},
"localization": {
"defaultLanguage": "en",
"languages": ["en"]
}
}Element type name rules
Type strings are exact — copy them exactly. Never invent casing variants.
| Correct | Wrong (do not use) |
|---|---|
"datepicker" | "datePicker", "DatePicker", "date-picker" |
"singleCheckbox" | "SingleCheckbox", "single_checkbox" |
"dynamicTable" | "DynamicTable", "dynamic-table" |
"dynamicPanel" | "DynamicPanel" |
"multiSelect" | "MultiSelect", "multi-select" |
"toggleSwitch" | "ToggleSwitch", "toggle-switch" |
"richText" | "richtext", "RichText" |
"fileUpload" | "fileupload", "FileUpload" |
"phoneInput" | "PhoneInput", "phone-input" |
"listGrid" | "ListGrid", "list-grid" |
The canonical full list is in Common mistakes, entry 14.
Structure rules
settings
- Keep only settings that are actually used.
- If the user does not request a complex modal/dialog mode,
language,locale, andrenderModeare sufficient. - Do not invent unnecessary
dialog*,stepper*, orpageNavigation*properties if they are not in use.
pages
pagesdescribes layout only.- Every page must have a
name. rows[*].columns[*].elementRefpoints to theelementsmap.- Do not embed full element objects inside
pages.
elements
elementsis an object, not an array.- The key must match
element.name. - Every element must have at least
name,label, andtype. - If
pages[*].name = "pageCustomer", there must be anelements.pageCustomerentry withtype: "page".
localization
- For a single-language form, the minimum is:
defaultLanguagelanguages
- For multi-language forms, a
textssection may also be present.
dataSources
- Create only when the user genuinely needs external data or actions.
dataSourceNamereferences in elements must point to a real datasource.- If the form has no integration scenarios, it is better to omit
dataSources.
Name and reference rules
- All
namevalues must be unique throughout the structure. elementRefmust point to an existingelementsentry.- If an element is a container with inner fields, those child elements must also have unique
namevalues. - Do not reuse the same
namefor multiple different elements.
What the agent must do when extending an existing form
- Preserve existing
settings,pages,elements,localization, anddataSourcesunless the user explicitly asks to rebuild everything from scratch. - Modify only the related sections.
- When adding a new element, you must:
- add it to
elements - insert the
elementRefin the appropriatepage/row/column
- add it to
- When adding logic between fields, verify that both fields already exist.
Layout rules
- A single
rowcan have one or morecolumns. panel,tabs,accordion,dynamicPanel,dialog, andsplittercan have an inner layout.- Container inner layouts must remain in the NGX View Builder model, not via custom HTML.
- For a simple two-column layout, one
rowwith twocolumnsis sufficient.
Value shape rules
text,textarea,richText,codetypically store astring.number,sliderstore anumberorstringdepending onvalueStorageType.singleCheckbox,toggleSwitch,toggleButtontypically store aboolean.checkbox,multiSelecttypically store an array.select,radio,dropdown,autocompletetypically store a single value.dateRangemust return an object withdateFromanddateTo.dynamicPanelanddynamicTabletypically store an array of objects.numberStepperstores anumber;timePickerstores a time string.signaturePadstores signature image data keyed under the element'sname.listBox,selectButtonstore a single value, or an array when multi-select/multipleis enabled.progressBarstores anumber.
Logic rules
- Use
visibleIf,disableIf,requireIf,readonlyIf,resetIffor boolean conditions. - Use
expressionto compute and write a value. - When logic depends on changes in another field, typically add
logicExecutionMode: "onChange". - Do not use self-reference
expression.
Validator field rules
Validators are separate sub-objects in the validators array. They have their own field names that differ from element-level logic fields:
| Element-level (correct placement) | Validator-level (correct placement) |
|---|---|
element.visibleIf | validator.condition |
element.requireIf | validator.applyIf |
element.expression | (does not exist on validators) |
Never put visibleIf, requireIf, readonlyIf, disableIf, expression, or resetIf inside a validator object. Never use the field name expression on a validator — the correct field is condition.
Polarity: condition is the failing check — the validator error is shown while condition evaluates to true. Use applyIf to run a validator only in certain cases (it runs while applyIf is truthy).
Correct:
json
{
"name": "age",
"type": "number",
"visibleIf": "{skipAge} != true",
"validators": [
{ "type": "min", "value": 0, "message": "Cannot be negative" },
{ "type": "max", "value": 120, "message": "Invalid age", "applyIf": "{country} == 'LT'" }
]
}What must not be generated
- Custom
Angularcomponents. - Non-existent NGX View Builder properties.
- Full element objects embedded in
pages. - Pseudo-code instead of real JSON.
- Empty wrappers or meta-properties with no real purpose.
Pre-return checklist
- Do all
elementRefvalues point to an existing element. - Does every
pagehave a correspondingelements[pageName]entry. - Do logic fields return the correct type.
- Are there no self-reference expressions.
- Is the correct element chosen for the task.
- Are there no unnecessary properties added.
- Are all
typestrings exact-cased (e.g.datepicker, notdatePicker)? - Do validators use
condition(error whentrue) andapplyIf— notexpression,visibleIf, or other element-level field names?
