Stream: questionnaire
Topic: EnableWhenExpression in repeatable group
Ilya Beda (Jul 28 2021 at 11:36):
Hello!
I hope you are doing well. I faced some issues when I try to define some conditional logic on repeatable group children.
I want to define some conditional expressions for an element of a repeatable group.
If there is an answer for the first, I would like to show the second question
I am using YAML and first-class extension notation to make the Questionnaire resource more readable.
resourceType: Questionnaire
item:
- type: group
linkId: my-group
repeats: true
item:
- type: text
linkId: first
- type: text
linkId: second
enableWhenExpression: '%parent.item.where(linkId='first').count()>0'
I am confused about how can I define parent in this case.
The best I did is
resourceType: Questionnaire
item:
- type: group
linkId: my-group
repeats: true
variable:
- name: parent
expression: '%context'
item:
- type: text
linkId: first
- type: text
linkId: second
enableWhenExpression: '%parent.answer.item.where(linkId='first').count()>0'
Unfortunately, this doesn't work obviously. I got all answers to my-group
, but I need only a current one.
How can I define %parent
to achieve desired behavior?
Lloyd McKenzie (Jul 28 2021 at 13:39):
You shouldn't need to use enableWhenExpression at all there. You'd just have enableWhen.question=first, operator=exists, answerBoolean=true
Paul Lynch (Jul 28 2021 at 14:58):
Also, what is %parent? I don't think there is such a thing, unless you create a variable named that. Speaking of which, if you do define a variable on the group, you can capture the value of item "first", and each repetition of the group will have its own copy of the variable.
Ilya Beda (Jul 28 2021 at 15:53):
It is my question - what should I use for %parent
to work exactly as I described.
@Lloyd McKenzie You are right, in this particular case, I can use enableWhen
instead of enableWhenExpression
.
However, I provided a very simplified version of the Questionnaire.
In the real-life case, I can't use enableWhen
, I need enableWhenExpression
.
Paul Lynch (Jul 28 2021 at 16:00):
So, I don't think you want %parent, but define a %first on the group, as "item.where(linkId='first')"
Paul Lynch (Jul 28 2021 at 19:43):
@Ilya Beda I am sorry I misunderstood what you were asking about %parent. I played with your test Questionnaire in LHC-Forms, and there I needed to change enableWhenExpression to calculatedExpression, because we don't support enableWhenExpression yet. However, I have a sample form to work that shows a count of either 0 or 1 for each repetition of the group, depending on whether the first question in each repetition is filled in. You can use the "Load From File" button at https://lhcforms.nlm.nih.gov/lhcforms to try the Questionnaire below. Each repitition of the group gets its own group variable. I would not recommend putting %context into a variable on the group, because that causes an endless loop, because the %context includes the child question answers, and the child question answers depend on that variable.
{
"resourceType": "Questionnaire",
"item": [
{
"type": "group",
"linkId": "my-group",
"text": "some group",
"repeats": true,
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "count",
"language": "text/fhirpath",
"expression": "item.where(linkId='first').count()"
}
}
],
"item": [
{
"type": "text",
"linkId": "first"
},
{
"type": "string",
"linkId": "second",
"readonly": true,
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%count"
}
}
]
}
]
}
]
}
Ilya Beda (Jul 29 2021 at 10:04):
Hi @Paul Lynch
Thank you for sharing your example.
I have a question about QuestionnaireResponse produced by LHC-Forms.
It uses duplicated items with the same linkId if the type of "my-group" is a group.
{
"resourceType": "QuestionnaireResponse",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse|2.7"
],
"tag": [
{
"code": "lformsVersion: 29.0.3"
}
]
},
"status": "completed",
"authored": "2021-07-29T09:59:46.758Z",
"item": [
{
"linkId": "my-group",
"text": "some group",
"item": [
{
"linkId": "first",
"answer": [
{
"valueString": "43"
}
]
},
{
"linkId": "second",
"answer": [
{
"valueString": 1
}
]
}
]
},
{
"linkId": "my-group",
"text": "some group",
"item": [
{
"linkId": "second",
"answer": [
{
"valueString": 0
}
]
}
]
},
{
"linkId": "my-group",
"text": "some group",
"item": [
{
"linkId": "first",
"answer": [
{
"valueString": "434"
}
]
},
{
"linkId": "second",
"answer": [
{
"valueString": 1
}
]
}
]
}
]
}
However, If I change type of the "my-group" to text it uses one item with multiple answers.
Also the calculatedExpression stops to work.
{
"resourceType": "QuestionnaireResponse",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaireresponse|2.7"
],
"tag": [
{
"code": "lformsVersion: 29.0.3"
}
]
},
"status": "completed",
"authored": "2021-07-29T09:58:02.083Z",
"item": [
{
"linkId": "my-group",
"text": "some group",
"answer": [
{
"valueString": "other",
"item": [
{
"linkId": "first",
"answer": [
{
"valueString": "qwer"
}
]
},
{
"linkId": "second",
"answer": [
{
"valueString": 0
}
]
}
]
},
{
"valueString": "qqq",
"item": [
{
"linkId": "first",
"answer": [
{
"valueString": "qqq"
}
]
},
{
"linkId": "second",
"answer": [
{
"valueString": 0
}
]
}
]
}
]
}
]
}
It looks inconsistent.
From my opinion the second form looks better to me because it doesn't duplicates items wiht the same linkId.
John Manning (Jul 29 2021 at 13:08):
Hey @Ilya Beda, how are you converting your Questionnaire resources to/from JSON/YAML? @Grey Faulkenberry created a package for this a while back using Dart, available here
Paul Lynch (Jul 29 2021 at 13:56):
Ilya Beda said:
It looks inconsistent.
I agree, but I think that is the way a QuestionnaireResponse is supposed to be. Answers to child items of a question go under item.answer.item.answer, while answers to child items of a group go under item.item.answer.
Ilya Beda (Jul 29 2021 at 14:25):
@John Manning I am using aidbox as FHIR server, it provides such a feature
Ilya Beda (Jul 29 2021 at 14:28):
@Paul Lynch does it mention somewhere in the spec?
Duplication of item with same id confuses a lot.
I am using item.item.answer when repeats: false
Paul Lynch (Jul 29 2021 at 14:36):
Ilya Beda said:
I am using item.item.answer when
repeats: false
I don't think that is correct unless the containing item is a group. If both are questions, https://www.hl7.org/fhir/questionnaireresponse-definitions.html#QuestionnaireResponse.item says: "When dealing with questions, nesting must occur within each answer because some questions may have multiple answers (and the nesting occurs for each answer)."
For when the containing item is a group, I don't see how you can avoid repeating the group and its linkId for each repetition of the group. But, the specification could be more clear on that point. You might want to submit a change request.
Lloyd McKenzie (Jul 29 2021 at 16:48):
If you're nesting a question within a question, the child must be nested under answer. repeats has no bearing on how nesting works. We've approved a change to make this rule more explicit.
Vadim Laletin (Jul 30 2021 at 08:05):
What about %context value in repeatable questions with subquestions? I was trying to re-write the example from @Paul Lynch. Here I need to calculate second-question
that depends on first-question
.
{
"resourceType": "Questionnaire",
"item": [
{
"type": "text",
"linkId": "top-question",
"text": "top question",
"repeats": true,
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "count",
"language": "text/fhirpath",
"expression": "item.where(linkId='first-subquestion').count()"
}
}
],
"item": [
{
"type": "text",
"text": "First subquestion",
"linkId": "first-subquestion"
},
{
"type": "string",
"linkId": "second-subquestion",
"text": "Second subquestion",
"readonly": true,
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%count"
}
}
]
}
]
}
]
}
Are there any ideas what should be placed into %context in my example?
I assume it must be answer[i] for each answer for 'top-question' . But according to the spec, %context shall refer to QuestionnaireResponse.item (https://build.fhir.org/ig/HL7/sdc/expressions.html#fhirpath-and-questionnaire)
Vadim Laletin (Jul 30 2021 at 10:15):
Possible solution - connected subquestions can be wrapped into a group under top-question. What do you think?
{
"resourceType": "Questionnaire",
"item": [
{
"type": "text",
"linkId": "top-question",
"text": "top question",
"repeats": true,
"item": [
{
"type": "group",
"text": "group",
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "count",
"language": "text/fhirpath",
"expression": "item.where(linkId='first-subquestion').count()"
}
}
],
"item": [
{
"type": "text",
"text": "First subquestion",
"linkId": "first-subquestion"
},
{
"type": "string",
"linkId": "second-subquestion",
"text": "Second subquestion",
"readonly": true,
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%count"
}
}
]
}
]
}
]
}
]
}
Paul Lynch (Jul 30 2021 at 13:52):
I think in
Vadim Laletin said:
What about %context value in repeatable questions with subquestions?
Are there any ideas what should be placed into %context in my example?
I assume it must be answer[i] for each answer for 'top-question' . But according to the spec, %context shall refer to QuestionnaireResponse.item (https://build.fhir.org/ig/HL7/sdc/expressions.html#fhirpath-and-questionnaire)
For items, %context is always the QuestionnaireResponse item. Is there a problem with that?
Vadim Laletin (Jul 30 2021 at 14:22):
@Paul Lynch In that case how it is possible to use first-question in caculatedExpression of the second-question for every top-question’s answer. %context will be set to QuestionnaireResponse.item that contains:
{
”linkId”: ”top-question”,
”answer”: […answer1, answer2, ….]
}
Where answer1 and answer2 are represented as:
{
”value”: {…},
”item”: [
{
”linkId”: ”first-question”,
”answer”: {…}
},
{
”linkId”: ”second-question”,
”answer”: {…} // THIS answer should be calculated from first-question for every top-question.answer[i]
}
]
}
Paul Lynch (Jul 30 2021 at 15:12):
I see. The problem is that the variable in the top-question group sees all of the answers for all of the repetitions, because the repetitions are under item.answer.item, and the top-question variable FHIRPath does not know which index is of interest (even if a separate copy of the variable could be created for each repetition). I think your work around of nesting the sub-questions inside a sub-group and putting the variable on the sub-group is the only way to make that work. Here is a complete form, without that workaround that demonstrates the issue in LHC-Forms (and can tried at https://lhcforms.nlm.nih.gov/lhcforms):
{
"status": "draft",
"resourceType": "Questionnaire",
"meta": {
"profile": [
"http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire|2.7"
],
"tag": [
{
"code": "lformsVersion: 29.1.2"
}
]
},
"item": [
{
"type": "string",
"required": false,
"repeats": true,
"linkId": "topq",
"text": "topq",
"extension": [
{
"url": "http://hl7.org/fhir/StructureDefinition/variable",
"valueExpression": {
"name": "count",
"language": "text/fhirpath",
"expression": "answer.item.where(linkId='name').answer.count()"
}
}
],
"item": [
{
"type": "string",
"required": false,
"repeats": true,
"linkId": "name",
"text": "name"
},
{
"type": "string",
"required": false,
"repeats": true,
"linkId": "count of names",
"text": "count of names",
"extension": [
{
"url": "http://hl7.org/fhir/uv/sdc/StructureDefinition/sdc-questionnaire-calculatedExpression",
"valueExpression": {
"language": "text/fhirpath",
"expression": "%count"
}
}
]
}
]
}
]
}
Last updated: Apr 12 2022 at 19:14 UTC