Naar hoofdinhoud gaan

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​

VeldTypeVerplichtOpmerkingen
logicalNametekenreeksjaMet uitgeversvoorvoegsel, in kleine letters snake_case.
displayNametekenreeksjaLeesbare naam van het formulier.
entitytekenreeksjaDe logische naam van de eigenaar-tabel.
descriptiontekenreeksneeDe regel die onder de titel in de titelbalk van het formulier wordt getoond.
icontekenreeksneeHet pictogram in de titelbalk van het formulier.
sectionsarrayeen van beideEen of meer secties met een titel — de oudere, platte indeling (zie hieronder).
tabsarrayeen van beideDe rijkere indeling met tabbladen (zie hieronder).
actionsarrayneeOntwerpbare 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)​

VeldTypeVerplichtOpmerkingen
titletekenreeksjaKop van de sectie.
columnsgeheel getaljaKolommen in de indeling, 1–4.
fieldsarrayjaVeldplaatsingen (zie hieronder).

Tabblad (indeling tabs)​

VeldTypeVerplichtOpmerkingen
idtekenreeksneeStabiele id voor de ontwerper.
titletekenreeksjaTitel van het tabblad.
icontekenreeksneePictogram naast de titel van het tabblad.
rowsarrayjaIndelingsrijen over de volle breedte: { id?, columns: 1–4, sections: [...] }, elke sectie { id?, title, icon?, span?, fields, timeline? }.

Veldplaatsing​

VeldTypeVerplichtOpmerkingen
fieldtekenreekszie opmerkingenDe 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.
labeltekenreeksneeLabel dat het standaardlabel overschrijft; zonder dit wordt de weergavenaam van het veld gebruikt.
controltekenreeksneeDe 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.
controlTypetekenreeksneeHet 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.
requiredbooleaansneeOf 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.
readOnlybooleaansneeOf 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.
controlPropsobjectneeDe 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)​

VeldTypeGelezen doorOpmerkingen
dateFormattekenreeksDate, 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.
trueLabeltekenreeksCheck, ToggleHet label voor de toestand "ja".
falseLabeltekenreeksCheck, ToggleHet label voor de toestand "nee".
rowsgeheel getalTextAreaAantal zichtbare regels, 2–20.
lookupEntitytekenreeksLookupLogische naam van de tabel waartegen het zoekveld wordt opgelost.
lookupViewtekenreeksLookupLogische 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.
lookupRowCountgeheel getalLookupHoeveel 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.
lookupPrimaryFieldtekenreeksLookupOverschrijving 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.
lookupSecondaryFieldtekenreeksLookupOverschrijving per besturingselement voor de tweede regel onder de naam, in plaats van het veld dat de doeltabel aanwijst. Afwezig gebruikt wat de tabel aanwijst.
lookupImageFieldtekenreeksLookupOverschrijving 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.
imageSizetekenreeksImage-veldHoe groot de voorvertoning van een Image-veld wordt gerenderd — sm (standaard, avatarformaat), md of lg (een opvallende afbeelding). Alleen zinvol voor een Image-veld.
labelTexttekenreeksLabelDe 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.
optionsarrayDropdownVaste 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.

VeldTypeVerplichtOpmerkingen
sourcesarray (1–10)jaDe tabellen die de tijdlijn leest, één item per tabel (zie hieronder).
pageSizegeheel getal (5–100)neeAantal items dat wordt getoond vóór Meer laden; 20 als het afwezig is.

Elke bron:

VeldTypeVerplichtOpmerkingen
entitytekenreeksjaDe logische naam van de brontabel.
regardingtekenreeksjaEen 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.
datetekenreeksjaEen datum/tijd-veld van de bron (inclusief systeemvelden zoals created_at_utc). De items worden erop gesorteerd, nieuwste eerst.
titletekenreeksjaHet veld dat als kop van elk item dient.
bodytekenreeksneeEen veld waarvan elk item de eerste woorden toont.
typetekenreeksneeEen 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.
statustekenreeksneeEen 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" }
]
}
]
}
]
}
]
}