Altinn / app-frontend-react

Altinn application React frontend
BSD 3-Clause "New" or "Revised" License
18 stars 31 forks source link

Expressions: Support options from expression result #1180

Open olemartinorg opened 1 year ago

olemartinorg commented 1 year ago

Currently

Options/code lists currently have a few variants we support:

I think we could replace the last (and possibly also the first) using expressions instead. That is, we can already look up keys in the data model using expressions, and after #1179 there should also be support for lists and objects.

The current configuration for source means you have to indicate where the group/array is in the data model, which text resource (?!) should indicate the label (as text resources can look up from repeating groups?) and which field in the data model the value should be derived from.

Note that:

Also, for the very simple case of a static list of options, you always have to provide both a value and a label.

In the future

We should only support two ways of configuring options, either via an expression or via an optionsId as before. For the absolutely simplest cases (i.e. yes/no) it should be sufficient to provide a basic list (using an expression):

["list", "yes", "no"]

The values we save in the data model will then be yes or no, but the labels are displayed via text resources (so if you have text resources for yes and no we might instead show Ja and Nei as labels).

If you want to provide your own labels, you can expand the expression:

["list",
  {"label": ["text", "simple.yes"], "value": "yes"},
  {"label": ["text", "simple.no"], "value": "no"}
]

And if you want to look up from the data model, from a repeating group structure, it can be done similarly:

["map",
  {
    "label": ["pluck", "label", ["argv", 0]],
    "value": ["pluck", "value", ["argv", 0]],
  },
  ["dataModel", "path.to.repeating.group"]
]

This would assume the suggested map function in #1179 is implemented, and supports mapping directly to an object propotype in addition to functions/closures.

To make this example as clear as possible, say we have this repeating group in dot-notation:

path.to.repeating.group[0].label = "Foo"
path.to.repeating.group[0].value = 1234
path.to.repeating.group[1].label = "Bar"
path.to.repeating.group[1].value = 4321

The resulting options would map to:

[
  {"label": "Foo", "value": 1234},
  {"label": "Bar", "value": 4321},
]

Combining optionsId with expressions

We should also support fetching a remote list of options, and using expressions to filter/change it before presenting it as options. This could be done by adding a function to fetch options based on an id, and return the options as a list of label/value objects which could then be filtered.

Related issue(s)

olemartinorg commented 12 months ago

Discussed this slightly here:

When implementing this, it would be very nice to have expression-support for something that works like the current start/stop filter (maybe a slice function?). With the next-gen Likert component (#936) it could be possible to fully get rid of the current start/stop filter that way, if it gets all questions from an options list and divides them up into smaller slices for presentation.