Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleaning up and adding lots of docs about options (svaralternativer) #1934

Open
wants to merge 29 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
96b4e18
Removing ancient and mostly irrelevant warning (for an older app-lib,…
Dec 3, 2024
0292ebd
Removing ancient warning
Dec 3, 2024
fbf396f
Removing reference to ancient code structure
Dec 3, 2024
2d15068
Improving the docs for dynamic code lists, and moving the sections ab…
Dec 3, 2024
0c9f9f4
Adding a section about static code lists defined in the component config
Dec 3, 2024
f39525f
Better highlighting
Dec 4, 2024
81141b9
Adding links to the options guide instead of individual components in…
Dec 4, 2024
82ecfad
Fixing broken link markdown
Dec 4, 2024
2760e51
Removing minimum version info (this version is getting old now)
Dec 4, 2024
0816b49
Making new sections for functionality, moving sections about sources
Dec 4, 2024
1cd478c
Improving titles and descriptions, adding an intro table for sources
Dec 4, 2024
39b22dc
Moving some stuff out, and making the top-most page introductory
Dec 4, 2024
0e78457
Clarifying that static isn't always static
Dec 4, 2024
c48c313
Rewriting section about repeating groups/structures
Dec 4, 2024
559cec4
Writing section about automatic cleanup
Dec 4, 2024
eca7236
Cleaning up in section about data-binding
Dec 5, 2024
1b93cc6
Writing about the storing the basic value in the data model
Dec 5, 2024
847898d
Weighting roughly according to the order the app developer should lea…
Dec 5, 2024
cb0668e
Preselection happens after filtering, but before sorting
Dec 5, 2024
ace0d0a
Writing about texts, adding a section about the label text and making…
Dec 9, 2024
d6784c6
Adding a bit about expression support in options from repeating struc…
Dec 9, 2024
690617f
Writing about filtering
Dec 10, 2024
39b3a4c
Writing about preselection, with a few warnings
Dec 10, 2024
aa94ea5
More about preselection + section about sorting
Dec 10, 2024
02a872b
Merge branch 'master' into options-rewrite
Dec 10, 2024
a6b5813
Fixing links
Dec 10, 2024
87c9b28
Fixing more links
Dec 10, 2024
6ba083b
Adding docs about argv and value
Dec 11, 2024
2bd2e78
Merge branch 'master' into options-rewrite
Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ The municipality of Sogndal wishes to collect information on the newcomers emplo
### In Local Development environment

1. Create the directory `App/options` if it does not exist.
2. The municipality of Sogndal has created a [static code list](/altinn-studio/guides/development/options/static-codelists) for **industries**: [industry.json](../industry.json). Download the file and place it in `App/options`.
3. Set up the values in the code list for **Years in work force** as an [open dynamic code list](/altinn-studio/guides/development/options/dynamic-codelists) in `App/options` (follow the directions in the documentation).
2. The municipality of Sogndal has created a [static code list](/altinn-studio/guides/development/options/sources/static) for **industries**: [industry.json](../industry.json). Download the file and place it in `App/options`.
3. Set up the values in the code list for **Years in work force** as an [open dynamic code list](/altinn-studio/guides/development/options/sources/dynamic) in `App/options` (follow the directions in the documentation).
Options:
Label | Data value
--------------|----------
Expand All @@ -62,8 +62,8 @@ The municipality of Sogndal wishes to collect information on the newcomers emplo

### Useful documentation

- [Static code lists](/altinn-studio/guides/development/options/static-codelists)
- [Dynamic code lists](/altinn-studio/guides/development/options/dynamic-codelists)
- [Static code lists](/altinn-studio/guides/development/options/sources/static)
- [Dynamic code lists](/altinn-studio/guides/development/options/sources/dynamic)

### Knowledge check
{{% expandsmall id="m4t1q1" header="What is the difference between static and dynamic options?" %}}
Expand Down Expand Up @@ -94,12 +94,12 @@ We want the user to be presented with a different set of options for the industr

### Tasks

1. [Send a dynamic query parameter](/altinn-studio/guides/development/options/#pass-query-parameters-when-fetching-options) with the Industry component based on the Sector.
1. [Send a dynamic query parameter](/altinn-studio/guides/development/options/sources/dynamic#query-parameters) with the Industry component based on the Sector.
2. Create a dynamic code list for _Industry_ with logic based on the value of the query parameter (hint: you can read the industry list from the JSON file).

### Useful documentation
- [How to pass query parameters when fetching options](/altinn-studio/guides/development/options/#pass-query-parameters-when-fetching-options)
- [How to configure dynamic code lists](/altinn-studio/guides/development/options/dynamic-codelists)
- [How to pass query parameters when fetching options](/altinn-studio/guides/development/options/sources/dynamic/#query-parameters)
- [How to configure dynamic code lists](/altinn-studio/guides/development/options/sources/dynamic)

### Knowledge check
{{% expandsmall id="m4t2q1" header="If a code list is configured with a mapping to the data model, what happens when the relevant field changes value?" %}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ Sogndal kommune ønsker å samle inn opplysninger om tilflytterens arbeidsituasj
### I lokalt utviklingsmiljø

1. Opprett mappen `App/options` hvis den ikke eksisterer.
2. Sogndal kommune har opprettet en [statisk kodeliste](/nb/altinn-studio/guides/development/options/static-codelists) for **bransjer**: [industry.json](../industry.json). Last ned filen og plasser den i `App/options`.
3. Sett opp alternativene for **År i arbeidslivet** som en [åpen dynamisk kodeliste](/nb/altinn-studio/guides/development/options/dynamic-codelists#åpne-dynamiske-kodelister) i mappen `App/options` (følg anvisning i dokumentasjonen).
2. Sogndal kommune har opprettet en [statisk kodeliste](/nb/altinn-studio/guides/development/options/sources/static) for **bransjer**: [industry.json](../industry.json). Last ned filen og plasser den i `App/options`.
3. Sett opp alternativene for **År i arbeidslivet** som en [åpen dynamisk kodeliste](/nb/altinn-studio/guides/development/options/sources/dynamic#åpne-kodelister) i mappen `App/options` (følg anvisning i dokumentasjonen).
Svaralternativer:
Label | Dataverdi
-----------|----------
Expand All @@ -60,8 +60,8 @@ Sogndal kommune ønsker å samle inn opplysninger om tilflytterens arbeidsituasj

### Nyttig dokumentasjon

- [Statiske kodelister](/nb/altinn-studio/guides/development/options/static-codelists)
- [Dynamiske kodelister](/nb/altinn-studio/guides/development/options/dynamic-codelists)
- [Statiske kodelister](/nb/altinn-studio/guides/development/options/sources/static)
- [Dynamiske kodelister](/nb/altinn-studio/guides/development/options/sources/dynamic)

### Forståelsessjekk
{{% expandsmall id="m4t1q1" header="Hva er forskjellen på statiske og dynamiske svaralternativer?" %}}
Expand Down Expand Up @@ -95,12 +95,12 @@ basert på hvilken sektor de har krysset av for.

### Oppgaver

1. [Send en dynamisk query-parameter](/nb/altinn-studio/guides/development/options/#sende-med-spørringsparametere-ved-henting-av-en-kodeliste) med Bransje-komponenten basert på Sektor.
1. [Send en dynamisk query-parameter](/nb/altinn-studio/guides/development/options/sources/dynamic#spørringsparametre) med Bransje-komponenten basert på Sektor.
2. Lag en dynamisk kodeliste for _Bransje_ med logikk basert på verdien til query-parameteren (hint: du kan lese inn bransjelisten fra json-filen).

### Nyttig dokumentasjon
- [Hvordan sende med spørringsparametre ved henting av kodelister](/nb/altinn-studio/guides/development/options/#sende-med-spørringsparametere-ved-henting-av-en-kodeliste)
- [Hvordan sette opp dynamiske kodelister](/nb/altinn-studio/guides/development/options/dynamic-codelists)
- [Hvordan sende med spørringsparametre ved henting av kodelister](/nb/altinn-studio/guides/development/options/sources/dynamic#spørringsparametre)
- [Hvordan sette opp dynamiske kodelister](/nb/altinn-studio/guides/development/options/sources/dynamic)

### Forståelsessjekk
{{% expandsmall id="m4t2q1" header="Om en kodeliste er satt opp med en mapping mot datamodellen, hva skjer når det aktuelle feltet endrer verdi?" %}}
Expand Down
263 changes: 14 additions & 249 deletions content/altinn-studio/guides/development/options/_index.en.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Code lists (options)
linktitle: Code lists
title: Options (code lists)
linktitle: Options
description: How to configure Options / Code lists for an app?
toc: true
weight: 40
Expand All @@ -9,255 +9,20 @@ aliases:
- /altinn-studio/reference/data/options
---

Altinn offers two different ways an application can use code lists - static and dynamic. Both is primarily exposed
through the options api from application, and are available at `{org}/{app}/api/options/{optionsId}`.
Checkbox, Dropdown, and RadioButton components will automatically be able to fetch such lists if you connect the
component to the option id in question. Not all dynamic code list have to be fetched from the options api - we can also
have code lists based on the values from a repeating structure in the datamodel.
Several of the form components in Altinn 3 use options. The concept referred to as options is sometimes also called _code lists_.

## Connect the component to options (code list)
The following components support options:

This is done by adding the optionId you would like to refer to either through the component UI in Designer or directly
in `FormLayout.json` as shown below:
| 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) |
| [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 |

```json
{
"id": "some-dropdown-component",
"type": "Dropdown",
"textResourceBindings": {},
"dataModelBindings": {},
"optionsId": "countries"
}
```

### Save label value in the datamodel
Sometimes you might wish to save the displayed value in the users chosen language to simplify creation of simple presentations of data without addtional lookups or a requirement to remember the label the user actually picked in case it have changed over time.

This is performed by having a separate ``dataModelBindings`` with the key ``"label":`` in addition to ``"simpleBinding":``

```json
{
"id": "dropdown-component",
"type": "Dropdown",
"dataModelBindings": {
"simpleBinding": "soknad.nyGaranti.loyvetype",
"label":"soknad.nyGaranti.loyvetypeLabel"
},
"optionsId": "biler"
}
```


## Pass query parameters when fetching options

Options supports query parameters when making the api call, the parameter `language` is added automatically.

### Pass static query parameters

You can add static query parameters by setting the `queryParameters` property on the component:

```json
{
"id": "some-dropdown-component",
"type": "Dropdown",
"textResourceBindings": {
"title": "NyGarantiLoyvetype"
},
"dataModelBindings": {
"simpleBinding": "soknad.nyGaranti.loyvetype"
},
"required": true,
"optionsId": "loyvetyper",
"queryParameters": {
"loyvetype": "garanti"
}
},
```

In the example above the parameter `?loyvetype=garanti` will be added to the request.

### Pass dynamic query parameters based on the data model

You can add dynamic parameters by setting the `mapping` property on the component:

```json
{
"id": "some-dropdown-component",
"type": "Dropdown",
"textResourceBindings": {
"title": "NyGarantiLoyvetype"
},
"dataModelBindings": {
"simpleBinding": "soknad.nyGaranti.loyvetype"
},
"required": true,
"optionsId": "loyvetyper",
"mapping": {
"soknad.transportorOrgnummer": "orgnummer"
}
},
```

In the example above, the query parameter `orgnummer={nr}`, where `{nr}` is the value of `soknad.transportorOrgnummer`
will be set.
If an option is setup with mapping and the given data field changes app-frontend will refetch the option. This can be
used to dynamically decide which choices are available based on information given by the end user.

Passing query parameters from repeating groups is also supported by adding an index indicator for the relevant indexes.
Example for a group:

```json
{
"id": "dropdown-group",
"type": "Dropdown",
"textResourceBindings": {
"title": "Select city"
},
"dataModelBindings": {
"simpleBinding": "Group.City"
},
"required": true,
"optionsId": "cities",
"mapping": {
"Group[{0}].Country": "country"
}
},
```

For nested groups follows the same pattern but with an additional index indicator for the nested group:

```json
{
"id": "dropdown-nested-group",
"type": "Dropdown",
"textResourceBindings": {
"title": "Select city"
},
"dataModelBindings": {
"simpleBinding": "Group.SubGroup.City"
},
"required": true,
"optionsId": "cities",
"mapping": {
"Group[{0}].SubGroup[{1}].Country": "country"
}
},
```

For a complete example of how this is setup see our [demo app.](https://altinn.studio/repos/ttd/dynamic-options-rep)

{{%notice warning%}}

**Applies to applications using version 7.4.0 or older of the nuget packages** - https://github.com/Altinn/app-lib-dotnet/release

<br>

During PDF-generation the app will try to call the same option endpoint as app-frontend does.
We currently have a weakness where mapping parameters not are included in this request, see issue [#7903.](https://github.com/Altinn/altinn-studio/issues/7903)

A possible workaround here is to return an empty array when the PDF-generator asks for options with empty query params, example:

```c#
string someArg = keyValuePairs.GetValueOrDefault("someArg");
string someOtherArg = keyValuePairs.GetValueOrDefault("someOtherArg");

if (string.IsNullOrEmpty(someArg) || string.IsNullOrEmpty(someOtherArg)) {
return await Task.FromResult(new List<AppOption>());
}
```

Notice that this wil result in the option value and not the label being present as the end users answer.
{{% /notice%}}

### Store metadata for the parameters used to retrieve options in tha datamodel

You can store metadata for the parameters used to retrieve options in the datamodel by setting the `metadata` property
on the components `dataModelBinding` property:

```json
{
"id": "some-dropdown-component",
"type": "Dropdown",
"textResourceBindings": {
"title": "NyGarantiLoyvetype"
},
"dataModelBindings": {
"simpleBinding": "soknad.nyGaranti.loyvetype",
"metadata": "soknad.transportorOrgnummer"
},
"required": true,
"optionsId": "loyvetyper",
"mapping": {
"soknad.transportorOrgnummer": "orgnummer"
}
},
```

This configuration will store the metadata of the retrieved options as a comma separated string in the
field `soknad.transportorOrgnummer` in the datamodel.

## Description and HelpText

`description` and `helpText` is supported by options in apps that use version v7.8.0 or higher. `description` and
`helpText` can be displayed by the components `RadioButtons` and `Checkboxes` by providing the option list with the
mentioned properties.

Descriptions and HelpTexts can be provided to `options` in the same way that a `label` is provided, in either static or
dynamic code lists. One can also use them in options based on repeating groups in the `source` attribute.

```json
[
{
"value": "norway",
"label": "Norge",
"description": "This is a description",
"helpText": "This is a help text"
},
{
"value": "denmark",
"label": "Danmark"
}
]
```

```cs
var options = new AppOptions
{
Options = new List<AppOption>
{
new AppOption
{
Label = "Ole",
Value = "1",
Description = "This is a description",
HelpText = "This is a help text"
},
new AppOption
{
Label = "Dole",
Value = "2"
}
}
};
```

Descriptions and help texts used in options based on repeating groups can be set up with dynamic text-resources in the
same way as labels, described in
[options based on repeating groups](repeating-group-codelists).

```json
{
"id": "checkboxes-component-id",
"type": "Checkboxes",
...
"source": {
"group": "some.group",
"label": "checkboxes.label",
"description": "checkboxes.descripiton",
"helpText": "checkboxes.helpText",
"value": "some.group[{0}].someField"
}
},
```
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.

{{<children />}}
Loading
Loading