Stream: questionnaire
Topic: enable-when
Grahame Grieve (Jul 11 2019 at 20:57):
Consider this questionnaire, from the validator test cases:
Grahame Grieve (Jul 11 2019 at 20:57):
<?xml version="1.0" encoding="UTF-8"?> <Questionnaire xmlns="http://hl7.org/fhir"> <id value="questionnaire-enableWhen-test" /> <language value="en-US" /> <text> <status value="generated" /> <div xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <p>enableWhen test</p> </div> </text> <url value="http://hl7.org/fhir/us/hai/Questionnaire/questionnaire-enableWhen-test" /> <status value="draft" /> <item> <linkId value="group" /> <text value="group" /> <type value="group" /> <repeats value="true" /> <item> <linkId value="condition" /> <text value="condition" /> <type value="boolean" /> <required value="true" /> <repeats value="false" /> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <type value="boolean" /> <enableWhen> <question value="condition" /> <operator value="="/> <answerBoolean value="true" /> </enableWhen> <required value="true" /> <repeats value="false" /> </item> </item> </Questionnaire>
Grahame Grieve (Jul 11 2019 at 20:58):
what does it mean to have a question that is required, but also has an enable-when on it? What is expected in the QR when the enable-when condition is false?
Grahame Grieve (Jul 11 2019 at 20:58):
Seems to me that this should be an illegal combination - a question with a required=true can't have an enable-when
Grahame Grieve (Jul 11 2019 at 20:59):
Note that the questionnaire validation is all screwed up, which is why I'm looking at this....
Stefan Lang (Jul 11 2019 at 21:06):
Yes, seems there should be an invariant forbidding enable-when in combination with required=true.
And also leads to the question: how would one express "must be filled when enabled"?
Stefan Lang (Jul 11 2019 at 21:10):
So maybe just the definition of the "required" element should be widened to "... if used in combination with enabledWhen, the item shall only be present when the enabling condition resolves to true"?
Grahame Grieve (Jul 11 2019 at 21:12):
ah, already specified:
This element is a modifier because if enableWhen is present for an item, "required" is ignored unless one of the enableWhen conditions is met
Grahame Grieve (Jul 11 2019 at 21:12):
buried in the middle of the comments
Grahame Grieve (Jul 11 2019 at 21:13):
given that definition, then, this QR should generate 2 errors:
Grahame Grieve (Jul 11 2019 at 21:13):
<?xml version="1.0" encoding="UTF-8"?> <QuestionnaireResponse xmlns="http://hl7.org/fhir"> <id value="questionnaireResponse-enableWhen-test" /> <text> <status value="generated" /> <div xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <p>enableWhen test response</p> </div> </text> <questionnaire value="http://hl7.org/fhir/us/hai/Questionnaire/questionnaire-enableWhen-test" /> <status value="completed" /> <!-- group 0: spacer --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> <!-- group 1: condition true, present (valid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> <!-- group 2: condition false, present (invalid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="false" /> </answer> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> <!-- group 3: condition true, absent (invalid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> </item> <!-- group 4: condition false, absent (valie) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> </QuestionnaireResponse>
Grahame Grieve (Jul 11 2019 at 21:14):
let me know if any disagrees
Stefan Lang (Jul 11 2019 at 21:15):
agreed.
Grahame Grieve (Jul 11 2019 at 22:09):
I have some more questions about enableWhen. The enable-when clause of a question cannot depend on the answer of a question that is an item inside the question, right?
Grahame Grieve (Jul 11 2019 at 22:09):
nor does it make sense for the answer to come from another heirarchy than the one the question is in?
Grahame Grieve (Jul 11 2019 at 22:10):
and it doesn't really make sense for the question it depends on to come after the question either, right?
Grahame Grieve (Jul 11 2019 at 22:11):
the first would be an error on the definition, and the third would be a warning on the definition?
Stefan Lang (Jul 12 2019 at 07:04):
There may be cases where the second actually exists, especially when you try to represent forms that have been designed for paper in a 1:1 manner. This may not be a good idea, but it happens all the time.
So that would be warning (or no issue) for being out of hierarchy.
Brian Postlethwaite (Jul 12 2019 at 13:37):
Value can definitely come from outside the hierarchy. Lots of preceding sections to produce a formula for eligibility the enable when met those conditions.
Brian Postlethwaite (Jul 12 2019 at 13:37):
All the rest seems good.
Brian Postlethwaite (Jul 12 2019 at 13:38):
I'm doing validation improvements in our R4 server at the moment too. Expecting updates to my test server next week.
Paul Lynch (Jul 12 2019 at 13:56):
I realize Grahame's question was about enableWhen, but we also have enableWhenExpression (described here, though the link is broken) which can depend on anything anywhere in the questionnaire or response. So, I am not sure we should care too much about what enableWhen depends on.
Grahame Grieve (Jul 12 2019 at 21:15):
Value can definitely come from outside the hierarchy
So that can get pretty complex. Given that the question being answered is at a node in the tree of answers, you find the relevant answer for checking the value by working up the tree looking for any relevant question with a matching linkId. You stop when you find any match.
Do you collect all the answers at the same level, or only the first?
Grahame Grieve (Jul 12 2019 at 21:16):
I am not sure we should care too much about what enableWhen depends on.
Whether you use enableWhenExpression, or just simple enableWhen, it's unresolvable if the enabling of a question depends on it's own answer (or a child answer)
Brian Postlethwaite (Jul 12 2019 at 22:41):
I don't know about stopping at the first, it's all with that linkId (same question yes, but multiple answers - repeats and groups)
Grahame Grieve (Jul 12 2019 at 23:26):
you have to stop somewhere. Check out this Q /QR combination:
Grahame Grieve (Jul 12 2019 at 23:29):
<?xml version="1.0" encoding="UTF-8"?> <Questionnaire xmlns="http://hl7.org/fhir"> <id value="questionnaire-enableWhen-test" /> <language value="en-US" /> <text> <status value="generated" /> <div xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <p>enableWhen test</p> </div> </text> <url value="http://hl7.org/fhir/us/hai/Questionnaire/questionnaire-enableWhen-test" /> <status value="draft" /> <item> <linkId value="group" /> <text value="group" /> <type value="group" /> <repeats value="true" /> <item> <linkId value="condition" /> <text value="condition" /> <type value="boolean" /> <required value="true" /> <repeats value="false" /> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <type value="boolean" /> <enableWhen> <question value="condition" /> <operator value="="/> <answerBoolean value="true" /> </enableWhen> <required value="true" /> <repeats value="false" /> </item> </item> </Questionnaire>
Grahame Grieve (Jul 12 2019 at 23:29):
<?xml version="1.0" encoding="UTF-8"?> <QuestionnaireResponse xmlns="http://hl7.org/fhir"> <id value="questionnaireResponse-enableWhen-test" /> <text> <status value="generated" /> <div xmlns="http://www.w3.org/1999/xhtml" lang="en-US"> <p>enableWhen test response</p> </div> </text> <questionnaire value="http://hl7.org/fhir/us/hai/Questionnaire/questionnaire-enableWhen-test" /> <status value="completed" /> <!-- group 0: spacer --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> <!-- <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> --> </item> <!-- group 1: condition true, present (valid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> <!-- group 2: condition false, present (invalid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="false" /> </answer> </item> <item> <linkId value="enable-when" /> <text value="enable when condition true" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> <!-- group 3: condition true, absent (invalid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="true" /> </answer> </item> </item> <!-- group 4: condition false, absent (valid) --> <item> <linkId value="group" /> <item> <linkId value="condition" /> <text value="condition" /> <answer> <valueBoolean value="false" /> </answer> </item> </item> </QuestionnaireResponse>
Grahame Grieve (Jul 12 2019 at 23:29):
the condition only applies within the group. If you want conditions to apply outside the group, either that questionnaire is illegal - and it shouldn't be, or we need some consistent algorithm to determine how the applicable answer for a condition is resolved.
Grahame Grieve (Jul 13 2019 at 00:42):
actually, there's only one possible algorithm that can work:
- given sourceQ
- question that contains the enableWhen reference and targetQ
- question that the enableWhen references in the Q
- and also sourceA
- answer for sourceQ
and targetA
- answer for targetQ
in the QR
- work up from sourceQ
until you find the Q group that also contains targetQ
- this is groupQ
- work up from sourceA
until you find the QR group that matches groupQ
- this is groupA
- any targetA
in groupA
are input for the enableWhen decision
Grahame Grieve (Jul 13 2019 at 00:47):
I'm writing the validator that way.
Grahame Grieve (Jul 13 2019 at 00:53):
groupQ and groupA may be the base
Lloyd McKenzie (Jul 14 2019 at 03:09):
Enable When can depend on any preceding item. It isn't currently prohibited from depending on following nodes, but have no issue adding such a prohibition
Grahame Grieve (Jul 15 2019 at 10:13):
no prohibition - just a warning
Lloyd McKenzie (Jul 15 2019 at 14:43):
Would it be an error if an ancestor could be disabled by descendants?
Paul Lynch (Jul 15 2019 at 15:20):
Whether you use enableWhenExpression, or just simple enableWhen, it's unresolvable if the enabling of a question depends on it's own answer (or a child answer)
I agree that having the enabled status of a question depend on itself or a child element is undesirable. It would be like having an HTML & JavaScript page where there was a checkbox that disabled if you checked it. It is perfectly valid to make such a page, though.
From LHC-Forms's perspective, the expressions are black boxes into which the Questionnaire and QuesitonnaireResponse are dumped (along with the context node) and there is no telling what parts of those resources will get utilized. (All processing is handled by fhirpath.js). I don't see how it would be possible in our case to even provide a warning to the user.
When enabledWhen, it should be possible to provide a warning.
Paul Lynch (Jul 15 2019 at 15:21):
I'm writing the validator that way.
Are you writing it while kayaking past crocodiles?
Lloyd McKenzie (Jul 15 2019 at 15:25):
The problem with disabling an element based on child questions is that there's no mechanism to re-enable it. Is there a reason why we should allow something that we can't think of a real use-case for and which is likely to create grief?
Paul Lynch (Jul 15 2019 at 15:30):
My point is that was that we can't always catch those cases, so why complicate things? An HTML form does not worry about things like that, and it just adds more lines the to the spec. But, one could argue that we should put up the guard rails where we can; I don't have a strong opinion about it.
Lloyd McKenzie (Jul 15 2019 at 15:56):
Saying it's not legal is not the same as saying "implementations must detect illegal behavior".
Grahame Grieve (Jul 15 2019 at 21:58):
right. Validator calls it an error.
Sheridan Cook (Aug 14 2019 at 20:16):
I'm hitting an error when I try to validate a Questionnaire resource, that includes enableWhen boolean logic, using the test.fhir.org/r4 server.
-
que-7 rule states that if an operator is 'exists", the value must be a boolean (Expression: operator = 'exists' implies (answer is Boolean)).
-
I believe this invariant rule is the reason I get a conformance error of: "Concept not found (next char = \"t\", in \"true\") at character 1"...when I include the following in the example I'm validating:
"enableWhen": [ { "question" : "H4/Q5", "operator" : "exists", "answerBoolean": true } ], "enableBehavior": "all",
- The only way I've found around that error is to change the operator or remove answerBoolean entirely (other answer types can pass without problem).
- If I remove answerBoolean entirely I receive an error reminding me that enableWhen.answer[x] has a cardinality of 1..1.
I feel like this is a catch-22 but I'm assuming it's user error on my part. Is there another way that I should be formating enableWhen.answer under the specific circumstances where the boolean value of a previous question determines whether the later question should be displayed to the user?
Grahame Grieve (Aug 14 2019 at 20:41):
how are you validating?
Sheridan Cook (Aug 15 2019 at 14:10):
how are you validating?
Hi Grahame, I'm copy/pasting the full json Questionnaire resource into the text box on the server UI and selecting the operation: Validation.
When I click upload I receive the following error:
{
"resourceType" : "OperationOutcome",
"text" : {
"status" : "generated",
"div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><p>Concept not found (next char = \"t\", in \"true\") at character 1</p></div>"
},
"issue" : [
{
"severity" : "error",
"code" : "not-supported",
"details" : {
"text" : "Concept not found (next char = \"t\", in \"true\") at character 1"
},
"diagnostics" : "(00000000008873B0){FHIRServer.exe} [0000000000C883B0] Unknown function at TMethodImplementationIntercept + $7E37E0\r\n(00000000040DB242){FHIRServer.exe} [00000000044DC242] Unknown function at TMethodImplementationIntercept + $4037672\r\n(00000000040DD0F0){FHIRServer.exe} [00000000044DE0F0] Unknown function at TMethodImplementationIntercept + $4039520\r\n(0000000000049157){FHIRServer.exe} [000000000044A157] Unknown function at __dbk_fcall_wrapper + $2C0F7\r\n(0000000000049A5B){FHIRServer.exe} [000000000044AA5B] Unknown function at __dbk_fcall_wrapper + $2C9FB\r\n(0000000000011576){FHIRServer.exe} [0000000000412576]\r\n(00000000000115C1){FHIRServer.exe} [00000000004125C1]\r\n(00000000008873B0){FHIRServer.exe} [0000000000C883B0] Unknown function at TMethodImplementationIntercept + $7E37E0\r\n(0000000000886AD0){FHIRServer.exe} [0000000000C87AD0] Unknown function at TMethodImplementationIntercept + $7E2F00\r\n(00000000008863AE){FHIRServer.exe} [0000000000C873AE] Unknown function at TMethodImplementationIntercept + $7E27DE\r\n(0000000000886F9F){FHIRServer.exe} [0000000000C87F9F] Unknown function at TMethodImplementationIntercept + $7E33CF\r\n(00000000008BA28E){FHIRServer.exe} [0000000000CBB28E] Unknown function at TMethodImplementationIntercept + $8166BE\r\n(00000000008B88E7){FHIRServer.exe} [0000000000CB98E7] Unknown function at TMethodImplementationIntercept + $814D17\r\n(000000000085F13F){FHIRServer.exe} [0000000000C6013F] Unknown function at TMethodImplementationIntercept + $7BB56F\r\n(000000000085C89A){FHIRServer.exe} [0000000000C5D89A] Unknown function at TMethodImplementationIntercept + $7B8CCA\r\n(000000000085D3FF){FHIRServer.exe} [0000000000C5E3FF] Unknown function at TMethodImplementationIntercept + $7B982F\r\n(0000000000A7774C){FHIRServer.exe} [0000000000E7874C] Unknown function at TMethodImplementationIntercept + $9D3B7C\r\n(0000000003B195C9){FHIRServer.exe} [0000000003F1A5C9] Unknown function at TMethodImplementationIntercept + $3A759F9\r\n(00000000034795C2){FHIRServer.exe} [000000000387A5C2] Unknown function at TMethodImplementationIntercept + $33D59F2\r\n(00000000034780C9){FHIRServer.exe} [00000000038790C9] Unknown function at TMethodImplementationIntercept + $33D44F9\r\n(0000000003471DD4){FHIRServer.exe} [0000000003872DD4] Unknown function at TMethodImplementationIntercept + $33CE204\r\n(00000000034724B5){FHIRServer.exe} [00000000038734B5] Unknown function at TMethodImplementationIntercept + $33CE8E5\r\n(00000000034724B5){FHIRServer.exe} [00000000038734B5] Unknown function at TMethodImplementationIntercept + $33CE8E5\r\n(00000000034724B5){FHIRServer.exe} [00000000038734B5] Unknown function at TMethodImplementationIntercept + $33CE8E5\r\n(000000000346C2FC){FHIRServer.exe} [000000000386D2FC] Unknown function at TMethodImplementationIntercept + $33C872C\r\n(000000000346BCB2){FHIRServer.exe} [000000000386CCB2] Unknown function at TMethodImplementationIntercept + $33C80E2\r\n(000000000346B261){FHIRServer.exe} [000000000386C261] Unknown function at TMethodImplementationIntercept + $33C7691\r\n(000000000347CB6F){FHIRServer.exe} [000000000387DB6F] Unknown function at TMethodImplementationIntercept + $33D8F9F\r\n(000000000347CECE){FHIRServer.exe} [000000000387DECE] Unknown function at TMethodImplementationIntercept + $33D92FE\r\n(00000000038F66FF){FHIRServer.exe} [0000000003CF76FF] Unknown function at TMethodImplementationIntercept + $3852B2F\r\n(0000000000B34AD5){FHIRServer.exe} [0000000000F35AD5] Unknown function at TMethodImplementationIntercept + $A90F05\r\n(0000000003F01CC1){FHIRServer.exe} [0000000004302CC1] Unknown function at TMethodImplementationIntercept + $3E5E0F1\r\n(0000000003EF8C25){FHIRServer.exe} [00000000042F9C25] Unknown function at TMethodImplementationIntercept + $3E55055\r\n(0000000003EF5317){FHIRServer.exe} [00000000042F6317] Unknown function at TMethodImplementationIntercept + $3E51747\r\n(0000000003F13DED){FHIRServer.exe} [0000000004314DED] Unknown function at TMethodImplementationIntercept + $3E7021D\r\n(0000000000647F29){FHIRServer.exe} [0000000000A48F29] Unknown function at TMethodImplementationIntercept + $5A4359\r\n(000000000064989E){FHIRServer.exe} [0000000000A4A89E] Unknown function at TMethodImplementationIntercept + $5A5CCE\r\n(00000000005688F9){FHIRServer.exe} [00000000009698F9] Unknown function at TMethodImplementationIntercept + $4C4D29\r\n(000000000056690A){FHIRServer.exe} [000000000096790A] Unknown function at TMethodImplementationIntercept + $4C2D3A\r\n(000000000056A8BB){FHIRServer.exe} [000000000096B8BB] Unknown function at TMethodImplementationIntercept + $4C6CEB\r\n(0000000000569B6B){FHIRServer.exe} [000000000096AB6B] Unknown function at TMethodImplementationIntercept + $4C5F9B\r\n(000000000012E883){FHIRServer.exe} [000000000052F883] Unknown function at TMethodImplementationIntercept + $8ACB3\r\n(000000000001216D){FHIRServer.exe} [000000000041316D]\r\n(00000000000074D4){KERNEL32.DLL} [00007FFF7A6984D4] BaseThreadInitThunk + $14\r\n(000000000006D851){ntdll.dll } [00007FFF7B50E851] RtlUserThreadStart + $21\r\n"
}
]
}
Grahame Grieve (Aug 15 2019 at 18:45):
have you got an example of a full questionnaire?
Sheridan Cook (Aug 15 2019 at 18:58):
have you got an example of a full questionnaire?
Sure! QuestionnaireExample1.json is the one I'm trying to validate currently. I've removed all the answerBooleans except the one found on line 871 to make troubleshooting easier.
QuestionnaireExample2.json is an example I pulled off the R4 FHIR server (id: "bb") that shares the enableWhen.answerBoolean format that Example 1 has. Both fail validation with the same error noted above.
Lloyd McKenzie (Aug 19 2019 at 17:33):
@Grahame Grieve @Sheridan Cook Just checking if this got resolved or not.
Sheridan Cook (Aug 19 2019 at 17:54):
@Lloyd McKenzie not resolved yet. My solution for now is removing the answerBoolean from the test message to continue validation on other parts of the message, I'd like to know if that is the correct way of addressing that invariant or if the profile on the R4 profile needs to be modified.
Lloyd McKenzie (Aug 20 2019 at 02:12):
I think the invariant is correct. @Grahame Grieve ?
Grahame Grieve (Aug 20 2019 at 06:39):
it's still on my todo list...
Last updated: Apr 12 2022 at 19:14 UTC