Definitie van een modelgestuurd formulier
Schema-id: model-driven-form@2
Vervangen versie: model-driven-form@1
(model-driven-form-v1.schema.json) blijft
gepubliceerd en geregistreerd, zodat een al uitgerolde oplossing nog steeds wordt
gevalideerd tegen het schema waarvoor ze is geschreven. Versie 2 voegt alleen de optionele
controlProps.lookupView toe, dus elke v1-definitie is ook een geldige v2-definitie.
Machineleesbaar schema: model-driven-form.schema.json
De canonieke weergave van een formulier van modelgestuurde apps (sectie 6.7) — de indeling waarmee één record wordt bekeken en bewerkt. Wordt op dezelfde manier gevalideerd, of hij nu uit de ontwerper komt, uit een API-aanroep, van een AI-assistent of uit een oplossingsimport.
Structuur
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
logicalName | tekenreeks | ja | Met uitgeversvoorvoegsel, in kleine letters snake_case. |
displayName | tekenreeks | ja | Leesbare naam van het formulier. |
entity | tekenreeks | ja | De logische naam van de eigenaar-tabel. |
description | tekenreeks | nee | De regel die onder de titel in de titelbalk van het formulier wordt getoond. |
icon | tekenreeks | nee | Het pictogram in de titelbalk van het formulier. |
sections | array | een van beide | Een of meer secties met een titel — de oudere, platte indeling (zie hieronder). |
tabs | array | een van beide | De rijkere indeling met tabbladen (zie hieronder). |
actions | array | nee | Ontwerpbare acties voor de opdrachtbalk. |
Een formulier bevat ofwel sections ofwel tabs, niet geen van beide. Nieuwe
definities horen tabs te gebruiken; sections wordt geaccepteerd zodat bestaande
formulieren blijven werken, en wordt behandeld als één tabblad met rijen van één kolom.
Sectie (oudere indeling sections)
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
title | tekenreeks | ja | Kop van de sectie. |
columns | geheel getal | ja | Kolommen in de indeling, 1–4. |
fields | array | ja | Veldplaatsingen (zie hieronder). |
Tabblad (indeling tabs)
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
id | tekenreeks | nee | Stabiele id voor de ontwerper. |
title | tekenreeks | ja | Titel van het tabblad. |
icon | tekenreeks | nee | Pictogram naast de titel van het tabblad. |
rows | array | ja | Indelingsrijen over de volle breedte: { id?, columns: 1–4, sections: [...] }, elke sectie { id?, title, icon?, span?, fields, timeline? }. |
Veldplaatsing
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
field | tekenreeks | zie opmerkingen | De logische naam van het veld (moet op de tabel zijn gedefinieerd). Alleen weggelaten bij een plaatsing van het type Label, want dat is statische inhoud die aan geen enkel veld is gekoppeld. |
label | tekenreeks | nee | Label dat het standaardlabel overschrijft; zonder dit wordt de weergavenaam van het veld gebruikt. |
control | tekenreeks | nee | De logische naam van een aangepast besturingselement dat op de plaats van de standaard veldeditor wordt gekoppeld. Het besturingselement moet in de omgeving zijn geïnstalleerd; is dat niet zo, dan valt het veld terug op zijn standaard editor. |
controlType | tekenreeks | nee | Het ingebouwde besturingselement waarmee het veld wordt gerenderd (sectie 6.13.5). Een van Text, TextArea, Check, Toggle, Date, DateTime, Time, PersianDate, PersianDateTime, PersianTime, Lookup, Dropdown, Label. Laat weg om de Player de standaardinvoer voor het gegevenstype van het veld te laten kiezen. De Persian…-varianten renderen dezelfde kiezer als hun Gregoriaanse tegenhangers, maar openen op de Jalali-kalender, ongeacht de taal van de app; de opgeslagen waarde is nog steeds een Gregoriaans tijdstip. Label is statische Markdown-inhoud (controlProps.labelText) zonder gekoppeld veld. |
required | booleaans | nee | Of het veld op dit formulier bedrijfsmatig verplicht is (sectie 6.13.5) — de gebruiker moet het invullen voordat hij opslaat. Een zaak van het formulier, geen databasebeperking (elke tabelkolom is nullable); de Player dwingt het af in de browser, de server niet. Afwezig betekent dat de eigen IsRequired van het veld geldt. |
readOnly | booleaans | nee | Of het veld op dit formulier alleen-lezen wordt getoond (weergeven, niet bewerken). Een alleen-lezenveld wordt gerenderd als platte tekst zonder invoerelement. Ontbrekend is niet false: ontbreekt het, dan is het veld op een tabblad bewerkbaar maar in header alleen-lezen; een koptekstveld wordt dus bewerkbaar met een expliciete false. |
controlProps | object | nee | De eigenschappen van het gekozen besturingselement (zie hieronder). |
Voorrang van besturingselementen: een aangepaste control gaat vóór controlType, en dat
gaat weer vóór de standaard van het gegevenstype van het veld. Laat je beide weg, dan kiest de
Player de standaard.
Verplicht is een formulierregel, geen kolombeperking. required staat op de plaatsing,
dus hetzelfde veld kan op het ene formulier verplicht zijn en op het andere optioneel, en het
wordt alleen in de Player gecontroleerd wanneer de gebruiker opslaat. Tabelkolommen zijn op
databaseniveau altijd nullable (zoals in Power Apps), dus een record die via een import of
API-aanroep wordt aangemaakt, wordt nooit geweigerd vanwege een ontbrekend verplicht veld — de
enige waarde waarop de server staat, is het primaire veld (naamveld) van de tabel.
Eigenschappen van het besturingselement (controlProps)
| Veld | Type | Gelezen door | Opmerkingen |
|---|---|---|---|
dateFormat | tekenreeks | Date, DateTime, Time (en hun Persian…-varianten) | Weergaveformaat. Tokens: yyyy/yy, MMMM (volledige maandnaam)/MMM (kort)/MM/M, dd/d, HH, mm, ss; alle andere tekens zijn letterlijk. Afwezig gebruikt de standaard van de kalender — d MMMM yyyy voor Perzisch (bijv. 12 اردیبهشت 1405), yyyy/MM/dd voor Gregoriaans. |
trueLabel | tekenreeks | Check, Toggle | Het label voor de toestand "ja". |
falseLabel | tekenreeks | Check, Toggle | Het label voor de toestand "nee". |
rows | geheel getal | TextArea | Aantal zichtbare regels, 2–20. |
lookupEntity | tekenreeks | Lookup | Logische naam van de tabel waartegen het zoekveld wordt opgelost. |
lookupView | tekenreeks | Lookup | Logische naam van de weergave die de kolommen levert die in het resultatenpaneel van het zoekveld worden getoond. Afwezig laat het platform er een kiezen — zie viewType in het weergaveschema. |
lookupRowCount | geheel getal | Lookup | Hoeveel kandidaatrijen het paneel van het zoekveld tegelijk aanbiedt (1–500). Afwezig gebruikt de platformstandaard van 10. De server begrenst wat er ook wordt gevraagd — een kiezer is geen rapport. Na v2 toegevoegd door het schema ter plekke te verruimen: elke definitie die zonder deze eigenschap geldig was, is dat nog steeds. |
lookupPrimaryField | tekenreeks | Lookup | Overschrijving per besturingselement voor welk veld de naamregel van elke kandidaat is. Afwezig gebruikt het eigen primaire veld van de doeltabel; een naam die geen veld van de doeltabel is, wordt genegeerd. |
lookupSecondaryField | tekenreeks | Lookup | Overschrijving per besturingselement voor de tweede regel onder de naam, in plaats van het veld dat de doeltabel aanwijst. Afwezig gebruikt wat de tabel aanwijst. |
lookupImageField | tekenreeks | Lookup | Overschrijving per besturingselement voor welk File/Image-veld de afbeelding van elke kandidaat is, in plaats van de recordafbeelding van de doeltabel. Afwezig gebruikt de afbeelding van de tabel; een veld dat geen afbeelding is, wordt genegeerd. |
imageSize | tekenreeks | Image-veld | Hoe groot de voorvertoning van een Image-veld wordt gerenderd — sm (standaard, avatarformaat), md of lg (een opvallende afbeelding). Alleen zinvol voor een Image-veld. |
labelText | tekenreeks | Label | De vaste tekst van een Label-besturingselement, gerenderd als een kleine, veilige Markdown-subset: koppen met #/##/###, **bold**, *italic*, `code`, lijsten met - , links met [text](url) (alleen http/https/mailto/relatief) en {color:name}…{/color} (een toegestane kleurnaam of #hex). Ruwe HTML wordt nooit gerenderd. |
options | array | Dropdown | Vaste opties, elk { value, label }, die bij dit ene veld horen. Gebruik liever een keuzeset voor alles wat over velden of tabellen heen wordt hergebruikt: een set is een gedeelde, geversioneerde component met botsingsvrije waarden, terwijl deze opties een privélijst op één formulier zijn. Een veld met gegevenstype OptionSet negeert dit en haalt zijn opties uit zijn set. |
Eigenschappen die niet van toepassing zijn op het gekozen controlType, worden genegeerd,
niet geweigerd — dus als je het besturingselement van een veld wisselt en weer terugzet, gaat
de configuratie niet verloren.
Elk field waarnaar wordt verwezen, moet een veld zijn dat op de tabel is gedefinieerd — dat
wordt bij het opslaan afgedwongen, naast de schemavalidatie.
Tijdlijnsectie (timeline)
Een sectie in een tabblad kan een tijdlijn zijn in plaats van een groep velden: de records
van andere tabellen waarvan het zoekveld naar de geopende record wijst, samengevoegd en met de
nieuwste bovenaan — de e-mails, gesprekken en notities van een klant in één kolom. Een sectie
is het een of het ander: wanneer timeline aanwezig is, moet fields een lege array zijn.
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
sources | array (1–10) | ja | De tabellen die de tijdlijn leest, één item per tabel (zie hieronder). |
pageSize | geheel getal (5–100) | nee | Aantal items dat wordt getoond vóór Meer laden; 20 als het afwezig is. |
Elke bron:
| Veld | Type | Verplicht | Opmerkingen |
|---|---|---|---|
entity | tekenreeks | ja | De logische naam van de brontabel. |
regarding | tekenreeks | ja | Een zoekveld op de brontabel dat naar de tabel van het formulier wijst, of een zoekveld voor meerdere tabellen dat die tabel vermeldt. De tijdlijn toont de rijen waarvan de waarde de geopende record is. |
date | tekenreeks | ja | Een datum/tijd-veld van de bron (inclusief systeemvelden zoals created_at_utc). De items worden erop gesorteerd, nieuwste eerst. |
title | tekenreeks | ja | Het veld dat als kop van elk item dient. |
body | tekenreeks | nee | Een veld waarvan elk item de eerste woorden toont. |
type | tekenreeks | nee | Een keuzesetveld dat de rijen van de bron van elkaar onderscheidt. Elk item krijgt zijn pictogram en kleur van zijn optie, het filter toont één chip per optie, en Nieuw biedt één vooraf ingevulde vermelding per optie. |
status | tekenreeks | nee | Een veld dat naast de datum van elk item wordt getoond. |
Bij opslaan en bij import wordt elke naam gecontroleerd tegen de tabellen van de omgeving: de
brontabel moet bestaan, regarding moet naar de tabel van het formulier kunnen wijzen, date
moet een datum zijn, type moet een keuzeset zijn, en de rest moet bestaan. Een tijdlijn die
op een van deze punten faalt, wordt geweigerd (modelapps.form.timeline_*) in plaats van leeg
getekend. Verwijder je een veld dat een tijdlijn gebruikt, dan wordt het uit de tijdlijn
gehaald: een optioneel onderdeel vervalt, en een bron die zijn regarding, date of title
kwijtraakt, wordt verwijderd.
Voorbeeld
{
"logicalName": "par_invoice_main",
"displayName": "Main",
"entity": "par_invoice",
"description": "The invoice's main form",
"icon": "Receipt",
"tabs": [
{
"id": "tab-general",
"title": "General",
"rows": [
{
"id": "row-1",
"columns": 2,
"sections": [
{
"id": "sec-header",
"title": "Header",
"fields": [
{ "field": "par_name", "required": true },
{ "field": "par_total", "label": "Amount" },
{ "field": "par_number", "readOnly": true },
{
"field": "par_due",
"controlType": "Date",
"controlProps": { "dateFormat": "dd/MM/yyyy" }
},
{
"field": "par_paid",
"controlType": "Toggle",
"controlProps": { "trueLabel": "Paid", "falseLabel": "Unpaid" }
},
{ "field": "par_signature", "control": "par_signature_pad" }
]
}
]
}
]
}
]
}