Formulieren voorbeelden
Vooraf
Bespreking van een aantal voorbeelden van formulierdefinities, gaande van basic tot complex.
Voorbeelden
Basic
Basic formulier met een veldengroep (“fieldset”) waarin de gebruiker persoonsgegevens zoals voornaam, naam en leeftijd kan invoeren. Daarnaast zijn er nog twee reguliere velden zoals een “boolean” (ja/nee-veld) en een “multiline” (tekstvak).
{
"label": "Naam formulier",
"name": "naamFormulier",
"sectionBasedValidation": false,
"fields": [
{
"name": "persoonsgegevens",
"label": "Persoonsgegevens",
"type": "fieldset",
"fields": [
{
"name": "voornaam",
"label": "Voornaam",
"type": "text"
},
{
"name": "naam",
"label": "Naam",
"type": "text"
},
{
"name": "leeftijd",
"label": "Leeftijd",
"type": "number",
"default": 0
}
]
},
{
"name": "vegetarisch",
"label": "Vegetarisch?",
"type": "boolean"
},
{
"name": "opmerkingen",
"label": "Opmerkingen",
"type": "multiline"
}
]
}
Eenvoudig
Eenvoudig formulier dat een realistische subsidie-aanvraag illustreert. Het bevat meerdere read-only velden die automatisch worden ingevuld via computedWith en computedExpressions op basis van info uit andere formulieren (“contextDependencies” DMN-uitvoer en selectie van vereniging). Voor gevoelige velden zoals IBAN en e-mailadres wordt de bewerkbaarheid dynamisch gestuurd via expressies (bv. afhankelijk van de huidige taak “currentTask" en een keuzevinkje om gegevens te wijzigen). Het IBAN-veld gebruikt maskConfig met de vooraf gedefinieerde iban-masker én een conditions-validatie met level: "error" om het Belgische IBAN-formaat af te dwingen, inclusief een duidelijke errorMessage. Het formulier toont ook hoe je bijlagen verplicht maakt en hoe numerieke velden een standaardwaarde krijgen via “default".
{
"label": "Aanvraag subsidie zwerfvuil",
"name": "aanvraagZwerfvuil",
"fields": [
{
"name": "newMultilineDwx8Gx",
"label": "Indien dit een hercontrole is op vraag van het diensthoofd, staat hieronder een woordje uitleg",
"type": "multiline",
"read-only": true,
"computedWith": "opmerkingDiensthoofdHercontrole"
},
{
"name": "naamVereniging",
"label": "Naam vereniging",
"type": "text",
"required": true,
"read-only": true,
"computedWith": "dmnVereniging"
},
{
"name": "iban",
"label": "IBAN",
"type": "text",
"required": true,
"read-only": "ibanWijzigenNeeOfTaakFactuur",
"computedDefault": "dmnIban",
"maskConfig": {
"predefinedMask": "iban"
},
"conditions": [
{
"name": "geldigIBAN",
"level": "error",
"expression": "typeof $ === 'string' && $.length > 0? ($.substring(0,2) === 'BE' ? ((($.substring(4,16) + '1114') % 97 + $.substring(2,4)) % 97 === 1) : ((($.substring(2,14) + '1114') % 97 + $.substring(0,2)) % 97 === 1)):true",
"errorMessage": "Gelieve een geldig IBAN in te vullen"
}
]
},
{
"name": "ibanWijzigen",
"label": "Ik wil het gekende IBAN rekeningnummer wijzigen",
"type": "boolean",
"customComponentName": "skrHiddenComponent",
"default": false,
"visualisation": "checkbox"
},
{
"name": "voornaam",
"label": "Voornaam contactpersoon",
"type": "text",
"required": true,
"read-only": "taakAanvraagFOOfFactuur",
"computedDefault": "dmnVoornaam"
},
{
"name": "naam",
"label": "Naam contactpersoon",
"type": "text",
"required": true,
"read-only": "taakAanvraagFOOfFactuur",
"computedDefault": "dmnFamilienaam"
},
{
"name": "emailadres",
"label": "E-mailadres contactpersoon",
"type": "email",
"required": true,
"read-only": "emailWijzigenNeeOfTaakFactuur",
"computedDefault": "dmnEmail"
},
{
"name": "bestandMetBerekeningVanDePremie",
"label": "Bestand met berekening van de premie",
"type": "attachment2",
"required": true
},
{
"name": "aantalKilometersInHetTraject",
"label": "Aantal kilometers in het traject",
"type": "number",
"default": 0
},
{
"name": "berekendePremie",
"label": "Subsidiebedrag zwerfvuil",
"type": "number",
"required": true,
"help": "Vul hierin het berekende bedrag in van de subsidie",
"helpInLine": true
}
],
"computedExpressions": {
"loginVoornaam": "context.login.voornaam",
"loginNaam": "context.login.naam",
"loginRRN": "context.login.rrn",
"taakAanvraagFOOfFactuur": "(Boolean(currentTask) && currentTask.taskDefinitionKey === 'vulAanvraagInFO') || (Boolean(currentTask) && currentTask.taskDefinitionKey === 'taakLaadFactuurOp')",
"taakFactuurActief": "Boolean(currentTask) && currentTask.taskDefinitionKey === 'taakLaadFactuurOp'",
"taakFactuurNietActief": "Boolean(currentTask) && currentTask.taskDefinitionKey !== 'taakLaadFactuurOp'",
"dmnVoornaam": "context.outputDMN.voornaam",
"dmnFamilienaam": "context.outputDMN.familienaam",
"dmnIban": "context.outputDMN.iban",
"dmnEmail": "context.outputDMN.email",
"dmnVereniging": "context.selectieVereniging.naamVereniging",
"dmnPersoonGekendOfTaakFactuur": "$$.computedExpressions.dmnPersoonGekend === true || $$.computedExpressions.taakFactuurActief === true",
"emailWijzigenNeeOfTaakFactuur": "($$.computedExpressions.dmnPersoonGekend && $.emailWijzigen === false) || $$.computedExpressions.taakFactuurActief",
"ibanWijzigenNeeOfTaakFactuur": "($$.computedExpressions.dmnPersoonGekend && $.ibanWijzigen === false) || $$.computedExpressions.taakFactuurActief",
"opmerkingDiensthoofdHercontrole": "context.financieleGoedkeuringZwerfvuil.opmerkingVoorDeDossierbehandelaar"
},
"contextDependencies": {
"login": {
"documentByDefinitionKey": "login_data"
},
"selectieVereniging": {
"documentByDefinitionKey": "selectieVereniging"
},
"outputDMN": {
"documentByDefinitionKey": "outputDMN"
},
"financieleGoedkeuringZwerfvuil": {
"documentByDefinitionKey": "financieleGoedkeuringZwerfvuil"
}
}
}
Uitgebreid
Dit formulier bestaat uit meerdere secties en gebruikt ‘sectiegewijze validatie’ (“sectionBasedValidation") om per sectie te controleren of alles wel conform is ingevuld. Verplichte velden worden afgedwongen via de veldeigenschap ‘verplicht’ (“required”: true). In sectie 3 zijn de velden ‘alleen-lezen’ (“read-only”: true). Ze worden ‘automatisch ingevuld’ via computedWith met verwijzing naar computedExpressions berekend op basis van keuzes gemaakt in sectie 2. Het veld aantalPersonen staat default op 1 (“default”: 1) en heeft twee condities (min 1, max 10) met telkens een gepaste foutboodschap. Het merendeel van de computed expressions bevat ‘als … dan …’-logica met meerdere niveau’s in elkaar genest. Zie ook Formulierveld validatie en Formulier expressies voorbeelden voor details over validatieregels en computed expressions.
{
"label": "Naam formulier",
"name": "naamFormulier",
"sectionBasedValidation": true,
"sections": [
{
"name": "formulierSectie1",
"label": "Formulier sectie 1",
"fields": [
{
"name": "persoonsgegevens",
"label": "Persoonsgegevens",
"type": "fieldset",
"fields": [
{
"name": "voornaam",
"label": "Voornaam",
"type": "text",
"required": true
},
{
"name": "naam",
"label": "Naam",
"type": "text",
"required": true
},
{
"name": "leeftijd",
"label": "Leeftijd",
"type": "number",
"default": 0
}
]
},
{
"name": "vegetarisch",
"label": "Vegetariër",
"type": "boolean"
},
{
"name": "opmerkingen",
"label": "Opmerkingen",
"type": "multiline"
}
]
},
{
"name": "formulierSectie2",
"label": "Formulier sectie 2",
"fields": [
{
"name": "bezochteBestemmingen",
"label": "Welke bestemmingen heb je al bezocht?",
"type": "multichoice",
"choices": [
{
"name": "parijs",
"label": "Parijs"
},
{
"name": "lissabon",
"label": "Lissabon"
},
{
"name": "athene",
"label": "Athene"
},
{
"name": "praag",
"label": "Praag"
}
]
},
{
"name": "keuzeBestemming",
"label": "Welke bestemming wil je bezoeken?",
"type": "choice",
"required": true,
"choices": [
{
"name": "parijs",
"label": "Parijs"
},
{
"name": "lissabon",
"label": "Lissabon"
},
{
"name": "athene",
"label": "Athene"
},
{
"name": "praag",
"label": "Praag"
}
]
},
{
"name": "budget",
"label": "Wat is je budget?",
"type": "choice",
"required": true,
"default": "tussen1000en2000",
"choices": [
{
"name": "minder1000euro",
"label": "<1000"
},
{
"name": "tussen1000en2000",
"label": "1000 à 2000"
},
{
"name": "meerdan2000",
"label": ">2000"
}
]
}
]
},
{
"name": "formulierSectie3",
"label": "Formulier sectie 3",
"fields": [
{
"name": "reisvoorstel",
"label": "Reisvoorstel",
"type": "fieldset",
"fields": [
{
"name": "bestemming",
"label": "Bestemming",
"type": "text",
"read-only": true,
"computedWith": "keuzebestemmingLabel"
},
{
"name": "datumReis",
"label": "Datum reis",
"type": "date",
"read-only": true,
"computedWith": "reisdatum"
},
{
"name": "aantalDagen",
"label": "Aantal dagen",
"type": "number",
"read-only": true,
"computedWith": "aantalDagenReis",
"default": 0
},
{
"name": "naamHotel",
"label": "Naam hotel",
"type": "text",
"read-only": true,
"computedWith": "hotelNaam"
},
{
"name": "reiscode",
"label": "Reiscode",
"type": "number",
"read-only": true,
"computedWith": "reiscode",
"default": 0
}
]
}
]
},
{
"name": "formulierSectie4",
"label": "Formulier sectie 4",
"fields": [
{
"name": "eenheidsprijs",
"label": "Eenheidsprijs",
"type": "currency",
"read-only": true,
"computedWith": "eenheidsprijs"
},
{
"name": "aantalPersonen",
"label": "Aantal personen",
"type": "number",
"required": true,
"default": 1,
"conditions": [
{
"name": "aantalPersonenMinimum",
"level": "error",
"expression": "$ !== null ? $ > 0 : true",
"errorMessage": "Aantal personen moet groter zijn dan 0."
},
{
"name": "aantalPersonenMaximum",
"level": "error",
"expression": "$ !== null ? $ <= 10 : true",
"errorMessage": "Aantal personen mag niet meer zijn dan 10."
}
]
},
{
"name": "totaalprijs",
"label": "Totaalprijs",
"type": "currency",
"read-only": true,
"computedWith": "totaalprijs"
}
]
}
],
"computedExpressions": {
"keuzebestemmingLabel": "$.keuzeBestemming.selectedOption !== null ? $.keuzeBestemming.selectedOption.toString().charAt(0).toUpperCase() + $.keuzeBestemming.selectedOption.toString().slice(1) : null",
"reisdatum": "$.keuzeBestemming.selectedOption === 'athene' ? ($.budget.selectedOption === 'minder1000euro' ? '2026-07-12' : $.budget.selectedOption === 'tussen1000en2000' ? '2026-07-01' : $.budget.selectedOption === 'meerdan2000' ? '2026-07-15' : null) : $.keuzeBestemming.selectedOption === 'lissabon' ? ($.budget.selectedOption === 'minder1000euro' ? '2026-07-12' : $.budget.selectedOption === 'tussen1000en2000' ? '2026-07-01' : $.budget.selectedOption === 'meerdan2000' ? '2026-12-15' : null) : $.keuzeBestemming.selectedOption === 'praag' ? ($.budget.selectedOption === 'minder1000euro' ? '2026-10-05' : $.budget.selectedOption === 'tussen1000en2000' ? '2026-07-15' : $.budget.selectedOption === 'meerdan2000' ? '2026-08-05' : null) : $.keuzeBestemming.selectedOption === 'parijs' ? ($.budget.selectedOption === 'minder1000euro' ? '2026-10-04' : $.budget.selectedOption === 'tussen1000en2000' ? '2026-07-11' : $.budget.selectedOption === 'meerdan2000' ? '2026-09-01' : null) : null",
"aantalDagenReis": "$.keuzeBestemming.selectedOption === 'athene' ? ($.budget.selectedOption === 'minder1000euro' ? 7 : $.budget.selectedOption === 'tussen1000en2000' ? 10 : $.budget.selectedOption === 'meerdan2000' ? 15 : null) : $.keuzeBestemming.selectedOption === 'lissabon' ? ($.budget.selectedOption === 'minder1000euro' ? 5 : $.budget.selectedOption === 'tussen1000en2000' ? 8 : $.budget.selectedOption === 'meerdan2000' ? 12 : null) : $.keuzeBestemming.selectedOption === 'praag' ? ($.budget.selectedOption === 'minder1000euro' ? 6 : $.budget.selectedOption === 'tussen1000en2000' ? 15 : $.budget.selectedOption === 'meerdan2000' ? 21 : null) : $.keuzeBestemming.selectedOption === 'parijs' ? ($.budget.selectedOption === 'minder1000euro' ? 3 : $.budget.selectedOption === 'tussen1000en2000' ? 5 : $.budget.selectedOption === 'meerdan2000' ? 7 : null) : null",
"hotelNaam": "$.keuzeBestemming.selectedOption === 'athene' ? ($.budget.selectedOption === 'minder1000euro' ? 'Astoria' : $.budget.selectedOption === 'tussen1000en2000' ? 'Bristol' : $.budget.selectedOption === 'meerdan2000' ? 'Sirtaki' : null) : $.keuzeBestemming.selectedOption === 'lissabon' ? ($.budget.selectedOption === 'minder1000euro' ? 'Joao' : $.budget.selectedOption === 'tussen1000en2000' ? 'Pasteis' : $.budget.selectedOption === 'meerdan2000' ? 'Mole' : null) : $.keuzeBestemming.selectedOption === 'praag' ? ($.budget.selectedOption === 'minder1000euro' ? 'Czek' : $.budget.selectedOption === 'tussen1000en2000' ? 'Czak' : $.budget.selectedOption === 'meerdan2000' ? 'Bum' : null) : $.keuzeBestemming.selectedOption === 'parijs' ? ($.budget.selectedOption === 'minder1000euro' ? 'Corse' : $.budget.selectedOption === 'tussen1000en2000' ? 'Moulin Rouge' : $.budget.selectedOption === 'meerdan2000' ? 'Sorbonne' : null) : null",
"reiscode": "$.keuzeBestemming.selectedOption === 'athene' ? ($.budget.selectedOption === 'minder1000euro' ? 1 : $.budget.selectedOption === 'tussen1000en2000' ? 2 : $.budget.selectedOption === 'meerdan2000' ? 3 : null) : $.keuzeBestemming.selectedOption === 'lissabon' ? ($.budget.selectedOption === 'minder1000euro' ? 4 : $.budget.selectedOption === 'tussen1000en2000' ? 5 : $.budget.selectedOption === 'meerdan2000' ? 6 : null) : $.keuzeBestemming.selectedOption === 'praag' ? ($.budget.selectedOption === 'minder1000euro' ? 7 : $.budget.selectedOption === 'tussen1000en2000' ? 8 : $.budget.selectedOption === 'meerdan2000' ? 9 : null) : $.keuzeBestemming.selectedOption === 'parijs' ? ($.budget.selectedOption === 'minder1000euro' ? 10 : $.budget.selectedOption === 'tussen1000en2000' ? 11 : $.budget.selectedOption === 'meerdan2000' ? 12 : null) : null",
"eenheidsprijs": "$.keuzeBestemming.selectedOption === 'athene' ? ($.budget.selectedOption === 'minder1000euro' ? 899 : $.budget.selectedOption === 'tussen1000en2000' ? 1500 : $.budget.selectedOption === 'meerdan2000' ? 2100 : null) : $.keuzeBestemming.selectedOption === 'lissabon' ? ($.budget.selectedOption === 'minder1000euro' ? 780 : $.budget.selectedOption === 'tussen1000en2000' ? 1600 : $.budget.selectedOption === 'meerdan2000' ? 2500 : null) : $.keuzeBestemming.selectedOption === 'praag' ? ($.budget.selectedOption === 'minder1000euro' ? 850 : $.budget.selectedOption === 'tussen1000en2000' ? 1900 : $.budget.selectedOption === 'meerdan2000' ? 2700 : null) : $.keuzeBestemming.selectedOption === 'parijs' ? ($.budget.selectedOption === 'minder1000euro' ? 999 : $.budget.selectedOption === 'tussen1000en2000' ? 1455 : $.budget.selectedOption === 'meerdan2000' ? 2699 : null) : null",
"totaalprijs": "$$.computedExpressions.eenheidsprijs !== null && $.aantalPersonen !== null ? $$.computedExpressions.eenheidsprijs * $.aantalPersonen : null"
}
}
Complex
Complex formulier dat een dynamische lijst (“list") van onkosten opbouwt. Elk lijstitem bevat velden voor beschrijving, categorie, datum, bedrag (excl. btw) en btw-regime, aangevuld met een bijlage (“attachment2"). De samenvatting van elk item toont kerninfo via “containedInSummary": true en de titel wordt gegenereerd met “listItemTitle" in de computedExpressions. Het bedrag incl. btw (“bedragInclBtw") wordt afgeleid op basis van het gekozen btw-percentage. Het totaal (excl. btw) wordt berekend via een reduce-functie over de onkostenlijst. Tot slot zal de onkostenlijst gevisualiseerd worden als een subdoc indien deze geopend wordt via de backoffice.
{
"label": "Onkostennota",
"name": "onkostennota",
"sectionBasedValidation": true,
"fields": [
{
"name": "indiener",
"label": "Indiener",
"type": "fieldset",
"fields": [
{
"name": "voornaam",
"label": "Voornaam",
"type": "text"
},
{
"name": "naam",
"label": "Naam",
"type": "text"
},
{
"name": "email",
"label": "E-mailadres",
"type": "email"
},
{
"name": "afdeling",
"label": "Afdeling",
"type": "choice",
"choices": [
{
"name": "it",
"label": "IT"
},
{
"name": "hr",
"label": "HR"
},
{
"name": "financien",
"label": "Financiën"
},
{
"name": "communicatie",
"label": "Communicatie"
}
]
}
]
},
{
"name": "onkosten",
"label": "Onkosten",
"type": "list",
"initialLength": 1,
"minimumLength": 1,
"maximumLength": 20,
"labelForAdd": "Onkost toevoegen",
"labelForDelete": "Onkost verwijderen",
"fields": [
{
"name": "beschrijving",
"label": "Beschrijving",
"type": "text",
"containedInSummary": true
},
{
"name": "categorie",
"label": "Categorie",
"type": "choice",
"choices": [
{
"name": "vervoer",
"label": "Vervoer"
},
{
"name": "maaltijd",
"label": "Maaltijd"
},
{
"name": "accommodatie",
"label": "Accommodatie"
},
{
"name": "materiaal",
"label": "Materiaal"
},
{
"name": "andere",
"label": "Andere"
}
],
"containedInSummary": true
},
{
"name": "datum",
"label": "Datum onkost",
"type": "date"
},
{
"name": "bedrag",
"label": "Bedrag (excl. btw)",
"type": "currency",
"required": true,
"default": 0,
"conditions": [
{
"name": "bedragPositief",
"level": "error",
"expression": "$ !== null ? $ > 0 : true",
"errorMessage": "Bedrag moet groter zijn dan 0."
}
],
"containedInSummary": true
},
{
"name": "btwPercentage",
"label": "BTW",
"type": "choice",
"required": true,
"default": "btw21",
"choices": [
{
"name": "btw0",
"label": "0%"
},
{
"name": "btw6",
"label": "6%"
},
{
"name": "btw21",
"label": "21%"
}
]
},
{
"name": "bedragInclBtw",
"label": "Bedrag (incl. btw)",
"type": "currency",
"computedWith": "bedragInclBtw"
},
{
"name": "bijlage",
"label": "Bewijs (factuur of ticket)",
"type": "attachment2"
}
],
"customComponentName": "skrSubdocOverview",
"element": {
"computedExpressions": {
"listItemTitle": "'Nieuwe onkost: '.concat($.beschrijving !== undefined ? $.beschrijving : '')",
"bedragInclBtw": "$.bedrag !== undefined && $.btwPercentage !== undefined ? ($.btwPercentage.selectedOption === 'btw0' ? $.bedrag : $.btwPercentage.selectedOption === 'btw6' ? $.bedrag * 1.06 : $.bedrag * 1.21) : null"
}
}
},
{
"name": "totaal",
"label": "Totaal onkosten (excl. btw)",
"type": "currency",
"read-only": true,
"computedWith": "totaalOnkosten"
},
{
"name": "opmerkingen",
"label": "Opmerkingen",
"type": "multiline"
}
],
"computedExpressions": {
"totaalOnkosten": "$.onkosten !== undefined && $.onkosten.length > 0 ? $.onkosten.reduce((acc, item) => acc + (item.bedrag || 0), 0) : 0",
"subdocs_components": "\"components.1.listElementComponent\"",
"subdocs_manipulators": "$$.propertyManipulators.onkosten.nestedManipulators",
"subdocs_parent": "$$.propertyManipulators.onkosten"
}
}