Simplified/improved Likert #936
Labels
area/data-storage
area/layout
related to layouts/components
area/table
related to grid/list/repeating groups
kind/analysis
kind/feature-request
New feature or request
Background and problem description
The
Likert
component is visualized as a table, where:While the
Likert
component works well for this scenario, and has proved useful in the app it was originally made for, the structure and setup brings with it quite a few complexities. In order to set this up, you will have to:Object[]
), where:a. The question is put in one of the object properties (or a text resource key for the question, which causes the Likert component to rely on recursive - or at least two-level-deep - resolving of text resources)
b. The answer is supposed to be stored alongside the question in the same object
Group
container first, that contains theLikert
component as the only child. TheGroup
has to set the special property ofedit.mode = likert
which causes theGroup
with aLikert
child to transform into a Likert table as displayed above. Functionally, this intercepts our existing repeating Group code, and renders a special Likert table instead.edit.filter
property on theGroup
component to split one large repeatingObject[]
structure into multiple Likert scales, each containing a subset of the questions in the repeating structure. In thefrontend-test
app, this includes an example where the first 3 questions are optional, while the next 3 are required.The challenge
While this setup is quite powerful (one can define questions in the data model, and even add user-provided questions from previous pages using repeating groups), it might be overkill for simpler use-cases. Tying the use of the Likert component to a specific data model structure of repeating groups, and forcing this advanced setup, might deter some application developers from using the component.
Technical suggestion
One of the benefits of the
dataModelBindings
concept is the freedom you get to structure your data model to how you (or the receiving end) wants it, not how the layout components wants the structure to look like. In addition, because every row in the Likert table uses the sameLikert
component definition, each row by definition has to use the same text resource binding for the question, leading to smart hacks using text resource variables to look up the actual question from the data model.While I think the above section on the problem description can stand on its own, and those solving this issue should use their creativity to arrive at a good solution, I'll kick off the discussion by providing my own thoughts.
While most
dataModelBindings
usesimpleBinding
as the only key, we shouldn't be limiting ourselves to that. For example, theList
component fetches a structure from an API that is identical to the structure of repeating groups (Object[]
), and lets you select one of those rows. Note that the List component lets you store one or more of the cells/properties of that row/object into whatever location in the data model you'd like. In fact, it is very possible to extend theList
component to use a repeating group structure from the data model as the data source (letting you select one of the rows from a previous repeating group).Question sources
I think the
Likert
component should support a wide variety of question sources, for example:With a list of options being the source of questions, the number of radio buttons becomes a result of
<num of questions> x <num of choices>
. It would also allow for a much simpler setup of theLikert
component, such as:Or with questions and answers loaded externally:
Answer bindings (
dataModelBindings
)Now this begs the question; how do we bind these answers to the data model? I can think of two options, depending on the complexity of your setup, and how dynamic it is.
If you're implementing the static example above, with two fixed questions, you can get away with mapping these two answers to whatever locations in the data model you'd like (individually), such as:
Which might create a data model such as:
On the other hand, if you're using a varying set of questions, mapping each one manually might not be sustainable, so a more dynamic binding might be in order. We can use this to create a new repeating group structure:
Example generic mapping:
Resulting data model:
Note that with this solution, you don't have to include your
Likert
component as a child in aGroup
for the component to work properly, and requires no double-lookup in text resources. With mapping support, we can also vary questions depending on the answer to previous questions/searches/inputs/other parameters (although that would require the component to delete rows and/or remap its bindings when using a generic binding).Backwards compatibility
It might not be practical to rewrite the existing Likert component for this purpose, as the component is in already in use, and backwards compatibility (or a transition period) is required. We might instead want to write this as a new component, for example
RadioTable
, and deprecateLikert
in favor of that.Relevant issue(s)
RadioButtons
component does not represent just one radio button, but a group of them. ExpectingRadioButtons
to span multiple cells in aGrid
(with one radio button in each cell) would make it very hard to implement, but visually this would be exactly the same asLikert
. An implementation ofGrid
with auto-cell-spanningRadioButtons
inside of it would have to find a good solution for any amount (and variying amounts) of options perRadioButtons
, all while clamping the table to a fixed amount of rows/columns (as per theGrid
spec), which is impossible.Likert
solves this by the hard requirement to use the same answer options for every row, and dynamically adjusting the number of columns to it.RadioButton
(notRadioButtons
) #937The text was updated successfully, but these errors were encountered: