Skip to content

Commit

Permalink
Options rewrite fixes (#1952)
Browse files Browse the repository at this point in the history
Co-authored-by: Ole Martin Handeland <[email protected]>
  • Loading branch information
olemartinorg and Ole Martin Handeland authored Jan 11, 2025
1 parent b0b1265 commit 63c2f7d
Show file tree
Hide file tree
Showing 19 changed files with 100 additions and 92 deletions.
26 changes: 14 additions & 12 deletions content/altinn-studio/guides/development/options/_index.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@ aliases:
---

Several of the form components in Altinn 3 use options. By options, we mean a list of choices that can be selected by
the user. In the most basic use-cases you might [set up a list of options directly in the component configuration](sources/static),
the user. In the most basic use cases you might [set up a list of options directly in the component configuration](sources/static),
but often you'll want to fetch the options from a _code list_.

### Terms

There are subtle differences between the terms _options_ and _code lists_:

- **Options**: A list of choices that can be selected by the user. Think of the contacts in your phone. When you use
your contact list to dial someone, you are selecting from a list of options, and your phone uses the selected value
(the phone number) to dial the person.
- **Code list**: A list of codes and their corresponding value and texts. Think of
- **Options**: A list of choices that can be selected by the user. As an example, think of the contacts in your phone. When you use
your contact list to call someone, you are selecting from a list of options, and your phone uses the selected value
(the phone number) to call the person.
- **Code list**: A list of codes and their corresponding value and texts. This can for example be
the [ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes. This list contains codes (like `NO`
or `SE`) and their corresponding labels (like `Norway` or `Sweden`).

Expand All @@ -33,14 +33,16 @@ The following components support options:

| Component | Type | Use case |
|-------------------------------------------------------------------------|-----------------------|----------------------------------------------------------------------------------------------------|
| [Dropdown](../../../reference/ux/components/dropdown) | Single choice | Used to select a single option from a dropdown list |
| [RadioButtons](../../../reference/ux/components/radiobuttons) | Single choice | Used to select a single option from a list of radio buttons |
| [List](../../../reference/ux/components/listcomponent) | Single choice | Used to select a single option from a list/table (with one radio button per row) |
| [Dropdown](../../../reference/ux/components/dropdown) | Single choice | Used to select a single option from a dropdown list. |
| [RadioButtons](../../../reference/ux/components/radiobuttons) | Single choice | Used to select a single option from a list of radio buttons. |
| [List](../../../reference/ux/components/listcomponent) | Single choice | Used to select a single option from a list/table (with one radio button per row). |
| [Likert](../../../reference/ux/components/likert) | Single choice per row | Used to select a single option per row in a table, displayed as a scale. Commonly used in surveys. |
| [Checkboxes](../../../reference/ux/components/checkboxes) | Multiple choice | Used to select one or more options from a list of checkboxes |
| [MultipleSelect](../../../reference/ux/components/multipleselect) | Multiple choice | Used to select one or more options from a dropdown list |
| [FileUploadWithTag](../../../reference/ux/components/fileuploadwithtag) | Single choice | Used to upload a file and tag it with an option |
| [Checkboxes](../../../reference/ux/components/checkboxes) | Multiple choice | Used to select one or more options from a list of checkboxes. |
| [MultipleSelect](../../../reference/ux/components/multipleselect) | Multiple choice | Used to select one or more options from a dropdown list. |
| [FileUploadWithTag](../../../reference/ux/components/fileuploadwithtag) | Single choice | Used to upload a file and tag it with an option. |

In the categories below, you can learn more about how to produce a list of options, configure that option list to be used in a component, as well as common functionality supported across these components.
In the categories below, you can learn more about how to produce a code list, configure that list to be used in a
component in order to provide options in that component, as well as common functionality across
the previously mentioned components that support options.

{{<children />}}
19 changes: 10 additions & 9 deletions content/altinn-studio/guides/development/options/_index.nb.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ men ofte kommer svaralternativene til å hentes fra en _kodeliste_.

Det er noen små forskjeller mellom begrepene _svaralternativer_ og _kodelister_:

- **Svaralternativer**: En liste med valg som kan velges av brukeren. Tenk på kontaktene i telefonen din. Når du bruker
- **Svaralternativer**: En liste med valg som kan velges av brukeren. For eksempel, tenk på kontaktene i telefonen din. Når du bruker
kontaktlisten din for å ringe noen, velger du fra en liste med svaralternativer, og telefonen din bruker den valgte verdien
(telefonnummeret) for å ringe personen.
- **Kodeliste**: En liste med koder og deres tilhørende verdier og tekster. Tenk
- **Kodeliste**: En liste med koder og deres tilhørende verdier og tekster. Som et eksempel, tenk
[ISO 3166-1](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) landskoder. Denne listen inneholder koder (som `NO`
eller `SE`) og deres tilhørende ledetekst (som `Norge` eller `Sverige`).

Expand All @@ -34,14 +34,15 @@ Følgende komponenter støtter svaralternativer:

| Komponent | Type | Bruksområde |
|-------------------------------------------------------------------------|------------------|---------------------------------------------------------------------------------------------------------|
| [Dropdown](../../../reference/ux/components/dropdown) | Ett valg | Brukes for å velge ett alternativ fra en nedtrekksliste |
| [RadioButtons](../../../reference/ux/components/radiobuttons) | Ett valg | Brukes for å velge ett alternativ fra en liste med radioknapper |
| [List](../../../reference/ux/components/listcomponent) | Ett valg | Brukes for å velge ett alternativ fra en liste/tabell (med en radioknapp per rad) |
| [Dropdown](../../../reference/ux/components/dropdown) | Ett valg | Brukes for å velge ett alternativ fra en nedtrekksliste. |
| [RadioButtons](../../../reference/ux/components/radiobuttons) | Ett valg | Brukes for å velge ett alternativ fra en liste med radioknapper. |
| [List](../../../reference/ux/components/listcomponent) | Ett valg | Brukes for å velge ett alternativ fra en liste/tabell (med en radioknapp per rad). |
| [Likert](../../../reference/ux/components/likert) | Ett valg per rad | Brukes for å velge ett alternativ per rad i en tabell, vist som en skala. Vanlig i spørreundersøkelser. |
| [Checkboxes](../../../reference/ux/components/checkboxes) | Flere valg | Brukes for å velge ett eller flere alternativer fra en liste med avkrysningsbokser |
| [MultipleSelect](../../../reference/ux/components/multipleselect) | Flere valg | Brukes for å velge ett eller flere alternativer fra en nedtrekksliste |
| [FileUploadWithTag](../../../reference/ux/components/fileuploadwithtag) | Ett valg | Brukes for å laste opp en fil og knytte den til en 'tag'/merkelapp |
| [Checkboxes](../../../reference/ux/components/checkboxes) | Flere valg | Brukes for å velge ett eller flere alternativer fra en liste med avkrysningsbokser. |
| [MultipleSelect](../../../reference/ux/components/multipleselect) | Flere valg | Brukes for å velge ett eller flere alternativer fra en nedtrekksliste. |
| [FileUploadWithTag](../../../reference/ux/components/fileuploadwithtag) | Ett valg | Brukes for å laste opp en fil og knytte den til en 'tag'/merkelapp. |

I kategoriene under kan du lære mer om hvordan du produserer en liste med svaralternativer, kobler den til en komponent, samt om felles funkjsonalitet som kan brukes på tvers av disse komponentene.
I kategoriene under kan du lære mer om hvordan du produserer en kodeliste, kobler den til en komponent for å vise
frem svaralternativer, samt om felles funksjonalitet som kan brukes på tvers av disse komponentene.

{{<children />}}
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,20 @@ Some options for components may be dynamic. Either directly via [dynamic options
where some values may be [filtered](../filtering) out.

When the options are dynamic, the data model may contain values that are no longer valid. This can happen if the user
(or prefill) has selected an option that is no longer available. In such cases, to avoid the data model from containing
invalid values, unknown options are automatically removed from the data model.
(or prefill) has selected an option that is no longer available. In such cases, to prevent the data model from containing
invalid values, unknown options are automatically removed.

## How it works

When the form is loaded, the options for all components are fetched and compared to their values in the data model. Even
if a component is not visible (i.e. when on a page that is not currently shown), the app-frontend will still
if a component is not visible (i.e. on a page that is not currently shown, _not_ when it's
actively hidden using the `hidden` property), the app-frontend will still
check the options for that component and remove any values that are not in the options list.

This has some implications that you should be aware of:
- If you configure multiple components pointing to the same field in the data model, the options for all those components
should be the same. If they are not, the data model will be cleaned up to only contain the options that are valid for
all components.
should be the same. If they are not, the field in the data model will be adjusted to include only the options that
are valid for all components.
- If the component is not marked as `required`, the user can submit the form even if the value is removed from the data
model. If you want to ensure that the user selects a valid option, you should mark the component as required.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ hvor noen verdier kan være [filtrert](../filtering) bort.

Når svaralternativene er dynamiske, kan datamodellen inneholde verdier som ikke lenger er gyldige. Dette kan skje hvis
brukeren (eller forhåndsutfyllingen) har valgt et alternativ som ikke lenger er tilgjengelig. I slike tilfeller, for å
unngå at datamodellen inneholder ugyldige verdier, fjernes ukjente svaralternativer automatisk fra datamodellen.
forhindre at datamodellen inneholder ugyldige verdier, fjernes ukjente svaralternativer automatisk.

## Hvordan det fungerer

Når skjemaet lastes, hentes svaralternativene for alle komponenter og sammenlignes med verdiene i datamodellen. Selv om
en komponent ikke er synlig (dvs. når på en side som for øyeblikket ikke vises), vil app-frontend fortsatt
en komponent ikke er synlig (her mener vi at den er på en side som for øyeblikket ikke
vises, _ikke_ at den er aktivt skjult via `hidden`-egenskapen), vil app-frontend fortsatt
sjekke svaralternativene for den komponenten og fjerne eventuelle verdier som ikke er i svaralternativlisten.

Dette har noen implikasjoner som du bør være klar over:
- Hvis du konfigurerer flere komponenter som peker på det samme feltet i datamodellen, bør svaralternativene for alle
disse komponentene være de samme. Hvis de ikke er det, vil datamodellen ryddes opp for å kun inneholde de
disse komponentene være de samme. Hvis de ikke er det, vil feltet i datamodellen ryddes opp i slik at det kun inneholder de
svaralternativene som er gyldige for alle komponentene.
- Hvis komponenten ikke er merket som `required`, kan brukeren sende inn skjemaet selv om verdien fjernes fra
datamodellen. Hvis du vil sikre at brukeren velger et gyldig alternativ, bør du merke komponenten som påkrevd.
Expand All @@ -31,7 +32,7 @@ Dette har noen implikasjoner som du bør være klar over:
dvs. når brukeren åpner skjemaet i en nettleser.
- Automatisk opprydding skjer ikke når komponenten er merket som `hidden`. Derfor kan du også ha flere
komponenter som peker på det samme feltet i datamodellen, hvor noen er skjulte og noen er synlige. I slike
tilfeller vil bare de synlige komponentene ha svaralternativene sjekket og ryddet opp. Dette er også tilfelle
tilfeller vil bare de synlige komponentene ha svaralternativene sjekket og ryddet opp. Dette er også tilfellet
hvis en komponent er skjult fordi den er på en skjult side, eller inne i en annen skjult komponent.
Begrepet 'skjult' i denne sammenhengen refererer til [dynamiske uttrykk](../../../dynamics) brukt for å skjule
komponenter, ikke hvilke komponenter som for øyeblikket er synlige på siden.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Components using options will usually only store the value of the selected optio
usually sufficient, there are cases where you might want to store the label of the selected option as well. This can
be useful for displaying the selected option in a simple presentation of the data without additional lookups or if
you have a requirement to remember the label the user actually picked in case it has changed over time. When storing
the label in the data model, it will respect the users chosen language, look up the actual text from the text resources
the label in the data model, it will respect the user's chosen language, look up the actual text from the text resources
and store the final value in the data model.

This is configured by having a separate binding with the key `label`. The `label` binding should point to a field in the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,3 @@ datamodellen som inneholder en `string`-verdi:

Denne konfigurasjonen vil nå lagre metadataen til de hentede svaralternativene som en kommaseparert streng i
feltet `soknad.nyGaranti.loyvetypeMetadata` i datamodellen.
`
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@ Keep in mind that there are different approaches to making options dynamic:
even when dynamic options based on query parameters would be problematic.

Filtering options via the `optionFilter` property works with all of the above, and with
plain [static options](../../sources/static) as well. It makes it possible to use a [dynamic expression](../../../dynamics)
plain [static options](../../sources/static) as well. It allows you to use a [dynamic expression](../../../dynamics)
to filter out options based on the current state of the form.

### Configuration

In the example below, the `optionFilter` property is set to a dynamic expression that filters out the
option `should-be-removed`. Note that the `optionFilter` property accepts an expression for which options to keep,
so you should invert the logic to remove an option.
option `should-be-removed`. Note that the `optionFilter` property accepts an expression to determine which options
to keep. To remove an option, you should invert the logic. One way to do this is by writing the expression
inside a `not` function call.

The expression is evaluated for each option, and if it returns `true`, the option is _kept_. All other options are _removed_.

Expand Down Expand Up @@ -141,8 +142,8 @@ A few things to note about the configuration:
equal to the data set in the current `Dropdown` component.

{{% notice warning %}}
The example above relies on saving the form data to the backend and running data processing to update
the `UsedTypes` field. For this reason, it is still fully possible to select the same ingredient in multiple rows
The example above depends on saving the form data to the backend and running data processing to update
the `UsedTypes` field. For this reason, it is still entirely possible to select the same ingredient in multiple rows
in the repeating group if you're fast enough. When using a method like this you should
also [implement validation](../../../../../reference/logic/validation) to catch any duplicates that might slip through.
{{% /notice %}}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ alternativer brukeren kan velge mellom.

Legg merke til at det allerede finnes flere måter å gjøre svaralternativene dynamiske på:

1. Du kan bruke [dynamikk](../../../dynamics) for å skjule og vise helt forskjellige komponenter basert på en betingelse. Disse
1. Ved å bruke [dynamikk](../../../dynamics) for å skjule og vise helt forskjellige komponenter basert på en betingelse. Disse
komponentene kan være bundet til samme sted i datamodellen, men ha forskjellige svaralternativer. Merk at
[automatisk opprydding](../automatic-cleanup) kan fjerne verdier fra datamodellen når du bruker denne metoden.
2. Ved å bruke [dynamiske alternativer](../../sources/dynamic) og sende spørringsparametre til backenden, kan du skrive
Expand All @@ -19,16 +19,17 @@ Legg merke til at det allerede finnes flere måter å gjøre svaralternativene d
med data prosessering på backenden, kan dette være en kraftig måte å lage egendefinerte svaralternativer på, selv når dynamiske
alternativer basert på spørringsparametre ville være problematisk.

Filtrering av svaralternativer via `optionFilter`-egenskapen fungerer med alle de nevnte metodene, og med
vanlige [statiske svaralternativer](../../sources/static) også.
Filtrering av svaralternativer via `optionFilter`-egenskapen fungerer med alle de nevnte metodene, inkludert
[statiske svaralternativer](../../sources/static).
Dette gjør det mulig å bruke et [dynamisk uttrykk](../../../dynamics) for å filtrere ut svaralternativer basert
på den nåværende tilstanden i skjemaet.

### Konfigurasjon

I eksempelet under er `optionFilter`-egenskapen satt til et dynamisk uttrykk som filtrerer ut alternativet
`should-be-removed`. Merk at `optionFilter`-egenskapen settes opp med et uttrykk for hvilke alternativer som skal beholdes,
så du må snu om logikken for å fjerne et alternativ.
`should-be-removed`. Merk at `optionFilter`-egenskapen bruker et uttrykk for å bestemme hvilke alternativer som
skal beholdes. Om du vil fjerne alternativer, må du snu om logikken. Dette kan for eksempel gjøres ved å pakke inn
hele uttrykket i en `not`-funksjon.

Uttrykket evalueres for hvert svaralternativ, og hvis det returnerer `true`, beholdes alternativet. Alle andre alternativer fjernes.

Expand Down Expand Up @@ -133,7 +134,7 @@ Konfigurasjonen for dette eksempelet er som følger:

Noen ting å merke seg om konfigurasjonen:

1. De allerede brukte ingrediens-typene lagres i en komma-separert liste i feltet `UsedTypes` i datamodellen. Dette feltet
1. De allerede brukte ingredienstypene lagres i en kommaseparert liste i feltet `UsedTypes` i datamodellen. Dette feltet
oppdateres ved hjelp av [dataprosessering](../../../../../reference/logic/dataprocessing) som finner alle unike
ingredienstyper i `Ingredients`-lista.
2. Hvis vi bare sjekket `UsedTypes`-feltet mot `value`-verdien til den nåværende `Dropdown`-komponenten, ville alternativet
Expand Down
Loading

0 comments on commit 63c2f7d

Please sign in to comment.