Bundling along data to customize presentation of a questionnaire

Given a questionnaire with a list of questions, is there a (more or less) standardized way one could annotate the questions with expressions that would compare the question against some data supplied with the questionnaire?

I am conceptually thinking along the lines of

<Bundle>
   <Questionnaire/>
   <SomeDataContainer />
</Bundle>

Where a question could have an attribute along the lines of showExpression="data[question.id] == true" that would control whether or not the question should be shown, for instance.

I am thinking that the conceptual idea is general enough that it has been done a bunch of times before (like in SDC?), so would like to enquire before trying to come up with the wheel again.

Where does the “additional data” come from when you launch the form filler application?

What you would typically do is have a hidden question (or set of them) that would be set up to have an “initialValueExpression” that grabs the answer from either something from the launchContext or from a query. You would then use “enableWhen” based on the answer to that hidden question to turn other items on or off.

(You want to propoagate the external information into hidden questions because the launchContext is only available when initially filling the form and because query results might change over time or not be available to subsequent users/systems who are trying to validate the answers.)

1 Like

Thanks for answering. I get the hack of prepopulating hidden questions. That seems like a reasonable approach.

The Launch Context thing and Populatable Questionnaire seems promising. I guess I just need to do a deeper dive into this when time allows. I looked at some examples, but it was not immediately how this worked, but I guess this is a general concept that one can use to create ones own proprietary solution.

Where does the “additional data” come from when you launch the form filler application?

That is basically what this question is about - I am not sure :smile: I took a FHIR Fundamentals course without being able to answer questions as this, so that’s what I am wondering how to do. The conceptual solution we are looking for is this:

  1. Create a basic questionnaire using some Form Designer (like Structor).
  2. Manually annotate that questionnaire with some extensions that will make the following bits work
  3. Have a patient open an app for filling that form and then have the form filler frontend customize the rendering of that questionnaire and the form filling based on data specific for that instance of questionnaire filling (which questions to enable, data to use in drop-downs, etc).

It’s the step 3 we are unsure of how to do. We only know the fundamentals (from a class and Graham’s “Principles” book), but I can understand that we (FHIR or not) could

  • preprocess the questionnaire and embed the data into the questionnaire (this would essentially be equal to creating a new questionnaire from a template, so not ideal)
  • bundle the data alongside the questionnaire, somehow
  • make the form filler aware of some extension to the Questionnaire resource that allows it to dynamically fetch the required data from some other resource

I guess a Launch Context is essentially about the last point on that list?

Indicates to systems creating or updating a QuestionnaireResponse what types of information to pass in for internal processing.

In general, when you launch a questionnaire, the questionnaire will be passed the current user, patient and perhaps encounter. Some systems might pass the current research study or other “business context” that is relevant in their specific space. Any other information (e.g. “most recent lab X result”) would never be passed in by default - the Questionnaire would have to go query them (possibly using information such as ‘current patient’ to help filter).

For step 3, when a form is displayed, the form filler will automatically evaluate some of the SDC extensions, such as ‘variable’ and ‘initialValueExpression’ - which can be used to load certain information from the patient record and populate some answers to the QuestionnaireResponse (including ‘hidden’ answers) before the end users sees or interacts with it. All such answers are ‘part’ of the QuestionnaireResponse. Other questions can have logic that is driven by those pre-populated elements.

Launch context is a way of making contextual information available to the logic within the QuestionnaireResponse. (It’s hard to go query Conditions, Observations, etc. for the current patient, when you don’t know who the current patient is :>)

1 Like

In general, when you launch a questionnaire, the questionnaire will be passed the current user, patient and perhaps encounter.

Hmm … this was a bit abstract, but I feel it might be because of thinking in different contexts with different assumptions about the environment this is all happening in. I tried skimming through some sections of the SDC guide to see what this meant in practice.

Our context is simply is that we have a product that mostly produces data that is just exported as RTF documents (unstructured data) meant for direct human consumption to a patient journal (EHR). We might need to support exporting as FHIR in the future. We have created form solutions ourselves up until now, but every new form demanded programmer time for creating the schema. When creating a new product that would also deal with patient forms we mostly settled on using FHIR Questionnaire for rendering in our frontend as that freed us from creating a proprietary form designer (could use an existing one) and a form schema language of our own.

So the initial thought is that we will mostly just be using FHIR as a data format for storing forms and their responses, with no (so far?) interlinked data to Observations, etc. I see that we might need to have a “FHIR API” to support the frontend dynamically looking up ValueSets referenced in the Questionnaire (like when it is unfeasible to manually create a list of thousands of of medications for use in a drop down list), but otherwise I would assume the need for sourcing data to be minimal.

Seeing that most existing form filler and/or rendering solutions for SPAs were gigantic multi-megabyte bundles with unflexible styling options, while we only saw the need for a quite limited set of components with highly custom rendering for both the input form and the resulting questionnaire response, we decided to create the form filler components needed to render the questionnaire and the responses in the SPAs ourselves.

So when I am thinking “launching a questionnaire” I am thinking React (rendering) + JSON (the questionnaire) + Fetch (parse and process the questionnaire to fetch data based on metadata/expressions defined in the Questionnaire). But I assume this is a different (simpler/more concrete) context than you were thinking in :smiley: I assume that might be something like

  1. Give a url to a questionnaire to some FHIR library (HAPI, IBM FHIR Server, …)
  2. Get a Questionnaire object back
  3. Invoke some FHIR lib magic to resolve (fetch) all the data referenced in the questionnaire
  4. Render that to user?

So given my context, what could “questionnaire will be passed the current user, patient and perhaps encounter” mean? What part of a Questionnaire definition would require a processor of the questionnaire to obtains a current user? And do you mean an actual FHIR Resource (like Practicioner)?

Your description (“React (rendering) + JSON (the questionnaire) + Fetch”) is completely reasonable as a form filler. I mis-typed when I said “user”. I should have said “patient”. (You can grab user too, but I doubt you’ll care.) If you’re interested in retrieving other data to help drive form behavior, presumably you’ll need to know who the patient is to grab that. If you want to do that in a ‘standard’ way, you’ll need to grab the data from a FHIR interface. Nothing stops you from grabbing data from a proprietary interface, but there won’t be any ‘standard’ extensions that will know how to do that - and no other software will understand what extensions you create.

1 Like