Skip to content

Commit

Permalink
Merge pull request #4755 from open-formulieren/feature/4546-soft-requ…
Browse files Browse the repository at this point in the history
…ired-validation

Enable soft-required validation in the form designer
  • Loading branch information
sergei-maertens authored Oct 17, 2024
2 parents 2bddf50 + 6dffdd6 commit 57ffe50
Show file tree
Hide file tree
Showing 15 changed files with 143 additions and 37 deletions.
2 changes: 1 addition & 1 deletion docs/manual/forms/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ stap.

In deze sectie kunt u velden (ook wel componenten genoemd) naar de formulier
stap slepen en configureren. Kijk voor alle mogelijkheden naar het overzicht van
:ref:`formulier velden <manual_form_fields>` en naar de
:ref:`formuliervelden <manual_form_fields>` en naar de
:ref:`voorbeelden <manual_examples>`.

Bevestiging
Expand Down
2 changes: 1 addition & 1 deletion docs/manual/forms/form_fields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Validatie
---------

* **Verplicht**: Indien aangevinkt dan is dit veld verplicht voor de
eindgebruiker.
eindgebruiker. Sommige velden ondersteunen :ref:`niet-blokkerende verplichting <manual_forms_soft_required_fields>`.

* **Plugin**: U kunt gebruik maken van een externe plugin om een veld te
valideren. De waarde van het veld wordt naar de plugin gestuurd en
Expand Down
1 change: 1 addition & 0 deletions docs/manual/forms/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ De kern van Open Formulieren is uiteraard het beheren van formulieren.
variables
form_fields
logic
soft_required_fields
logic_dmn
translations
registrator
Expand Down
56 changes: 56 additions & 0 deletions docs/manual/forms/soft_required_fields.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
.. _manual_forms_soft_required_fields:

=================================================
Formuliervelden met niet-blokkerende verplichting
=================================================

Sommige velden laten toe om ze als "aangeraden" te markeren. In deze configuratie wordt
de gebruiker er van bewust gemaakt dat ze velden onbedoeld leeg laten, maar het blokkeert
ze niet om het formulier in te zenden.

.. note:: De meeste formuliervelden ondersteunen een
:ref:`validatie-optie <manual_form_fields_validation>` om het veld verplicht te
maken. Deze kan echter soms (om juridische redenen) niet gebruikt worden omdat een
gebruiker de aanvraag móet kunnen insturen en de organisatie verplicht is om
deze te beoordelen. Het is dan netjes om de gebruiker te kunnen wijzen op eventuele
kosten en gevolgen van het niet aanleveren van alle uitgevraagde gegevens.

Formulierconfiguratie
=====================

.. note:: deze documentatie gaat ervan uit dat je bekend met de basis van
:ref:`formulieren beheren <manual_forms_basics>`.

Het is belangrijk dat je in de betreffende formulierstap(pen) een component toevoegt
die de foutmeldingen weergeeft, anders krijgt de gebruiker geen feedback van eventuele
ontbrekende gegevens.

Voor elke relevante formulierstap:

1. Sleep zoals je gewend bent de velden uit het menu aan de linkerkant, en stel de
relevante configuraties in.
2. In het instellingenscherm, klik op de "Validatie"-tab.
3. Schakel vervolgens het selectievakje "Aangeraden (niet-blokkerend verplicht)" in.
Indien je deze niet kan aanvinken, controleer dan dat de optie "Verplicht" uitgevinkt
is - een veld kan namelijk niet tegelijk blokkerend en niet-blokkerend verplicht zijn.
4. Sla de veldinstellingen op.
5. Herhaal stap 1 tot en met 4 voor alle benodigde velden.
6. Klik in het menu aan de linkerkant de categorie "Opmaak" open.
7. Sleep het component "Foutmeldingen aangeraden velden" in de formulierstap.

* De inhoud zal enkel getoond worden als er "aangeraden velden" een lege waarde
hebben.
* Je kan het bericht voor de gebruiker naar wens instellen. Hierin kan je de
sjabloonvariabele ``{{ missingFields }}`` gebruiken die getoond wordt als lijst
van veld-labels met ontbrekende waarde.
* Andere sjabloonvariabelen of -uitdrukkingen kunnen niet gebruikt worden.
* Je kan hier ook vertalingen toepassen.

Ondersteunde velden
===================

De velden die "Aangeraden (niet-blokkerend verplicht)"-validatie ondersteunen zijn:

* Bestandsupload

Neem contact op indien je deze functionaliteit ook bij andere veldsoorten wenst.
18 changes: 9 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"dependencies": {
"@fortawesome/fontawesome-free": "^6.1.1",
"@open-formulieren/design-tokens": "^0.53.0",
"@open-formulieren/formio-builder": "^0.30.0",
"@open-formulieren/formio-builder": "^0.31.0",
"@open-formulieren/leaflet-tools": "^1.0.0",
"@open-formulieren/monaco-json-editor": "^0.2.0",
"@rjsf/core": "^4.2.1",
Expand Down
2 changes: 2 additions & 0 deletions src/openforms/forms/models/form_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,8 @@ def used_in(self) -> models.QuerySet:
to be used in bulk Form Definition querysets, you should use prefetch queries
for that.
"""
if not self.pk:
return Form.objects.none()
return (
Form.objects.filter(
_is_deleted=False,
Expand Down
8 changes: 8 additions & 0 deletions src/openforms/forms/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,14 @@ def test_num_components_calculated_on_save(self):

self.assertEqual(fd._num_components, 2)

def test_used_in_for_unsaved_fds(self):
FormFactory.create(generate_minimal_setup=False)
fd = FormDefinitionFactory.build()

used_in_num = fd.used_in.count()

self.assertEqual(used_in_num, 0)


class FormStepTestCase(TestCase):
def test_str(self):
Expand Down
24 changes: 12 additions & 12 deletions src/openforms/js/compiled-lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,12 @@
"value": "The text that will be displayed in the form step to save the current information. Leave blank to get value from global configuration."
}
],
"8M403q": [
{
"type": 0,
"value": "Soft required fields should be filled out, but empty values don't block the users' progress. Sometimes this is needed for legal reasons. A component cannot be hard and soft required at the same time."
}
],
"8NbOpb": [
{
"type": 0,
Expand Down Expand Up @@ -2739,6 +2745,12 @@
"value": "Select existing form definition"
}
],
"QL4SGQ": [
{
"type": 0,
"value": "Soft required"
}
],
"QLTh2N": [
{
"type": 0,
Expand All @@ -2757,12 +2769,6 @@
"value": "Whether the user is allowed to submit this form or not, and whether the overview page should be shown if they are not."
}
],
"QXsAuR": [
{
"type": 0,
"value": "Product to fetch prices for"
}
],
"QaPqxz": [
{
"type": 0,
Expand Down Expand Up @@ -5729,12 +5735,6 @@
"value": "Do not display the configured label and top line as the header in the fieldset."
}
],
"uuKVtO": [
{
"type": 0,
"value": "Product"
}
],
"vAZDY4": [
{
"type": 0,
Expand Down
24 changes: 12 additions & 12 deletions src/openforms/js/compiled-lang/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,12 @@
"value": "De tekst op de knop om de gegevens van de huidige stap op te slaan en het formulier te onderbreken. Laat dit veld leeg om de standaardinstelling te gebruiken."
}
],
"8M403q": [
{
"type": 0,
"value": "Aangeraden velden moeten in principe ingevuld worden, maar ontbrekende waarden blokkeren de voortgang niet. Dit is soms nodig voor juridische redenen. Een component kan niet tegelijk verplicht en aangeraden zijn."
}
],
"8NbOpb": [
{
"type": 0,
Expand Down Expand Up @@ -2756,6 +2762,12 @@
"value": "Selecteer een bestaande formulierdefinitie"
}
],
"QL4SGQ": [
{
"type": 0,
"value": "Aangeraden (niet-blokkerend verplicht)"
}
],
"QLTh2N": [
{
"type": 0,
Expand All @@ -2774,12 +2786,6 @@
"value": "Geeft aan of de gebruiker het formulier kan inzenden of niet, en of een overzichtspagina getoond wordt indien niet."
}
],
"QXsAuR": [
{
"type": 0,
"value": "Product waarvoor prijzen worden opgehaald"
}
],
"QaPqxz": [
{
"type": 0,
Expand Down Expand Up @@ -5751,12 +5757,6 @@
"value": "Verberg de koptekst en de lijn boven de veldengroep in het formulier."
}
],
"uuKVtO": [
{
"type": 0,
"value": "Product"
}
],
"vAZDY4": [
{
"type": 0,
Expand Down
35 changes: 35 additions & 0 deletions src/openforms/js/components/form/softRequiredErrors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {Formio} from 'formiojs';

import {localiseSchema} from './i18n';

const FormioContentField = Formio.Components.components.content;

const Component = Formio.Components.components.component;

class SoftRequiredErrors extends FormioContentField {
static schema(...extend) {
const schema = Component.schema(
{
type: 'softRequiredErrors',
key: 'softRequiredErrors',
label: '', // not displayed anyway
input: false,
html: undefined, // use default defined in formio-builder
},
...extend
);
return localiseSchema(schema);
}

static get builderInfo() {
return {
title: 'Soft required errors',
icon: 'triangle-exclamation',
group: 'custom_layout',
weight: 900,
schema: this.schema(),
};
}
}

export default SoftRequiredErrors;
1 change: 1 addition & 0 deletions src/openforms/js/components/formio_builder/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ const getBuilderOptions = () => {
content: true,
fieldset: true,
columns: true,
softRequiredErrors: true,
},
},
custom_preset: {
Expand Down
2 changes: 2 additions & 0 deletions src/openforms/js/formio_module.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import RadioField from './components/form/radio';
import SelectField from './components/form/select';
import SelectBoxesField from './components/form/selectBoxes';
import SignatureField from './components/form/signature';
import SoftRequiredErrors from './components/form/softRequiredErrors';
import TextArea from './components/form/textarea';
import TextField from './components/form/textfield';
import TimeField from './components/form/time';
Expand Down Expand Up @@ -64,6 +65,7 @@ const FormIOModule = {
editgrid: EditGrid,
datamap: Datamap,
addressNL: AddressNL,
softRequiredErrors: SoftRequiredErrors,
},
builders: {
webform: WebformBuilder,
Expand Down
1 change: 1 addition & 0 deletions src/openforms/js/lang/formio/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -405,5 +405,6 @@
"Verify": "Bevestigen",
"You must verify this email address to continue.": "Om door te gaan moet je dit e-mailadres bevestigen.",
"You must select at least {{minCount}} items.": "Zorg dat dit veld {{minCount}} of meer opties aangevinkt heeft.",
"Soft required errors": "Foutmeldingen aangeraden velden",
"": ""
}
2 changes: 1 addition & 1 deletion src/openforms/scss/components/builder/_builder.scss
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ div.flatpickr-calendar.open {
.tab-pane.active {
min-block-size: 50vh;

&:has(.formio-component-content) {
&:has(.formio-component-content, .formio-component-softRequiredErrors) {
min-block-size: 0;
}
}
Expand Down

0 comments on commit 57ffe50

Please sign in to comment.