FHIR Chat · Where to store those logic to determine conditional required · questionnaire

Stream: questionnaire

Topic: Where to store those logic to determine conditional required


view this post on Zulip SAM TSAI (Oct 05 2021 at 16:54):

Q1: Do you want to receive text notification ? (Yes /No)
Q2: What is your mobile phone number ?

Q2 will become required if Q1's answer is 'Yes'

How to put this kind of logic into Questionnaire ?

view this post on Zulip Lloyd McKenzie (Oct 05 2021 at 17:49):

The SDC implementation guide covers defining constraints using the questionnaire-constraint extension as well as making 'required' expression-based via cqf-expression

view this post on Zulip Brian Postlethwaite (Oct 06 2021 at 08:36):

In my server you just mark q2 as mandatory, and put an enablewhen to activate it only when the answer is yes.

view this post on Zulip Brian Postlethwaite (Oct 06 2021 at 08:38):

Alternatively as Lloyd points out, but it's the constraint expression.
http://hl7.org/fhir/R4/extension-questionnaire-constraint.html

view this post on Zulip Ilya Beda (Oct 06 2021 at 09:56):

@SAM TSAI I have created a sample for your case.
Please check it here https://sdc.beda.software/#/simple-conditional-question

view this post on Zulip Lloyd McKenzie (Oct 06 2021 at 13:29):

Didn't think of that. @Brian Postlethwaite's solution is better as it doesn't rely on extensions at all :)

view this post on Zulip Tilo Christ (Oct 06 2021 at 14:31):

But I thought the original question was to make the mobile number optional when q1 is no, and mandatory when it is yes? Not to remove the entire question? BTW I was unable to find the portion of the spec that bases "required" on an expression, as mentioned by @Lloyd McKenzie in his first response.

view this post on Zulip Brian Postlethwaite (Oct 06 2021 at 20:34):

The invariant I linked above does that.
(I'll throw an example together)

view this post on Zulip Brian Postlethwaite (Oct 06 2021 at 22:22):

something like this on the parent of the 2 questions

<extension url="http://hl7.org/fhir/StructureDefinition/questionnaire-constraint">
        <extension url="key">
            <valueId value="Q2-req" />
        </extension>
        <extension url="severity">
            <valueCode value="error" />
        </extension>
        <extension url="human">
            <valueString value="Q2 is required when Q1 is yes" />
        </extension>
        <extension url="expression">
            <valueString value="item.where(linkId='Q1').answer.value = 'yes' implies item.where(linkId='Q2').answer.value.exists()" />
        </extension>
    </extension>

view this post on Zulip Tilo Christ (Oct 07 2021 at 16:49):

OK, I got the impression from @Lloyd McKenzie' initial response that there was a way to really affect the required flag. So it seems one can make it required dynamically, but without the visual hints (asterisk at the label etc.) that a filler might use for fields with a required attribute?

view this post on Zulip Lloyd McKenzie (Oct 07 2021 at 17:03):

You can affect the required flag:

<required>
   <extension value="http://hl7.org/fhir/StructureDefinition/cqf-expression">
        <valueExpression>
            <expression value="your expression here"/>
        </valueExpression>
    </extension>
</required>

view this post on Zulip Brian Postlethwaite (Oct 07 2021 at 22:57):

In my example above I forgot to add in the location field to indicate which field was in error.
The cqf-expression format requires that the context be the item itself, so has to either look into it's children (not common here) or try navigating down to the item from the top, which has issues if there are repeating groups involved.
Where I've done this, the invariant expression is far more concise as can put it as close as possible to the item (usually parent item) and then access to the sibbling question is far easier.

%response.item.where(linkId='group1').item.where(linkId='Q1').answer.value = 'yes' implies %response.item.where(linkId='group1').item.where(linkId='Q2').answer.value.exists()

or (using the top level select to locate the common parent - which you won't be able to do if this is a repeating group)

%response.item.where(linkId='group1')
.select(item.where(linkId='Q1').answer.value = 'yes' implies item.where(linkId='Q2').answer.value.exists())

vs

item.where(linkId='Q1').answer.value = 'yes' implies item.where(linkId='Q2').answer.value.exists()

also that expression evaluation will process many more nodes, rather than the few actually involved.

view this post on Zulip Tilo Christ (Oct 10 2021 at 11:10):

I'm currently building out my implementation of the 'constraint' extension. What is the semantics of the "severity" field? I cannot find a list of all the permitted codes, and I am not sure whether there are any differences in behaviour expected?

view this post on Zulip Lloyd McKenzie (Oct 10 2021 at 16:45):

Severity indicates whether it's an error, warning, information or best-practice issue if the constraint is violated. It's supposed to have the same binding as constraint on StructureDefinition. Can you submit a technical correction for us to fix that @Tilo Christ ?

view this post on Zulip Brian Postlethwaite (Oct 10 2021 at 17:46):

It is bound with a required binding, you can only see that on the full structure tab in the extension.

view this post on Zulip Lloyd McKenzie (Oct 10 2021 at 19:14):

So it is. So this is a rendering issue then. When an extension is being defined, the binding ought to show up in both the differential view. @Grahame Grieve?

view this post on Zulip Tilo Christ (Oct 10 2021 at 20:11):

The description of the extension is saying the questionnaire can only be complete if the constraint is not violated. Can it still be complete if only a warning constraint is violated?

view this post on Zulip Lloyd McKenzie (Oct 10 2021 at 20:51):

Yes. Though ideally the warning should be displayed an the user should confirm the warning isn't an issue before marking it as complete.

view this post on Zulip Brian Postlethwaite (Oct 10 2021 at 21:36):

Also note that if you're doing the storage side too, the invariant can be ignored if the item is in draft mode.


Last updated: Apr 12 2022 at 19:14 UTC