google / android-fhir

The Android FHIR SDK is a set of Kotlin libraries for building offline-capable, mobile-first healthcare applications using the HL7® FHIR® standard on Android.
https://google.github.io/android-fhir/
Apache License 2.0
463 stars 241 forks source link

Implement initial value in questionnaire #372

Closed jingtang10 closed 3 years ago

jingtang10 commented 3 years ago

Implement the initial value as specified here: https://www.hl7.org/fhir/questionnaire-definitions.html#Questionnaire.item.initial

MuhammadSalman-7214 commented 3 years ago

@jingtang10 I have some questions:

  1. what and when we want to show initial value
  2. We have initial values as list in the code so how do we want to show specific value
  3. For which widgets we want to have initial values

can you please tell the answers? thanks

jingtang10 commented 3 years ago

Hi @MuhammadSalman-7214

@jingtang10 I have some questions:

  1. what and when we want to show initial value

The initial values should be displayed if there isn't already an answer in the questionnaire response.

From the spec:

One or more values that should be pre-populated in the answer when initially rendering the questionnaire for user input.

The user is allowed to change the value and override the default (unless marked as read-only). If the user doesn't change the value, then this initial value will be persisted when the QuestionnaireResponse is initially created. Note that initial values can influence results. The data type of initial[x] must agree with the item.type, and only repeating items can have more then one initial value.
  1. We have initial values as list in the code so how do we want to show specific value

You may have multiple initial values for repeated questions. But I would not worry about that for now. Focus on single answer questions.

  1. For which widgets we want to have initial values

Probably all of them. But most importantly text inputs, checkboxes, radio buttons, drop down lists.

can you please tell the answers? thanks

Thanks!

MuhammadSalman-7214 commented 3 years ago

@jingtang10 initial values list is empty for checkboxes, radio buttons, and drop downs, so how do I set the initial values for all these widgets? kindly advise. Thanks

jingtang10 commented 3 years ago

If the initial value list is empty that means there isn't an initial value set for the question. So you don't need to do anything.

MuhammadSalman-7214 commented 3 years ago

so that means we don't have to set initial value for checkboxes, radio buttons, and drop downs? because we don't have any one widget in the application among these that contain any initial values @jingtang10

jingtang10 commented 3 years ago

https://www.hl7.org/fhir/questionnaire-profile-example-ussg-fht.json.html has a question with intial value.

Can you also ask on the fhir chat for more examples?

I'm not sure what you mean by we don't have to set initial values. It's an optional field, so as I said you don't need to do anything if it's not there. Does this make sense?

Thanks.

MuhammadSalman-7214 commented 3 years ago

I understand what you are saying that I don't have to set if there isn't any initial value, but what I am saying is currently in the json forms in the application, I don't have any initial optional value, and I want some to set and verify my implementation, are you getting my point now @jingtang10 ?

jingtang10 commented 3 years ago

Thanks @MuhammadSalman-7214. Do you have a proposal how we can address that issue?

MuhammadSalman-7214 commented 3 years ago

Yes, if we can add the initial values in just one check box, radio button and spinner in any json form in the application, that will solve our problem @jingtang10. Thanks.

jingtang10 commented 3 years ago

Please feel free to do that in a PR.

The only that I would say is some of these forms are examples we've taken from other projects for demo purposes. So it's important we keep them intact.

But you can change the patient registration example or feel free to add another example questionnaire to demonstrate initial values.

MuhammadSalman-7214 commented 3 years ago

Okay, thanks

jingtang10 commented 3 years ago

Thanks @MuhammadSalman-7214.

I have a couple of questions

  1. How do you deal with multiple initial values - I see that you use initial[0] to read the first value. Can you make it explicit either we're only copying 1 intial value (and throw exception if there're more intial values), or fix it for multiple intial values.
  2. How does this play with pre-filled questionnaire responses. @joiskash

Thanks!

MuhammadSalman-7214 commented 3 years ago

Thanks @MuhammadSalman-7214.

I have a couple of questions

  1. How do you deal with multiple initial values - I see that you use initial[0] to read the first value. Can you make it explicit either we're only copying 1 intial value (and throw exception if there're more intial values), or fix it for multiple intial values.
  2. How does this play with pre-filled questionnaire responses. @joiskash

Thanks!

@jingtang10 for point 1, there should be only 1 initial value for any of the check boxes, radio buttons, edit texts and drop downs as we should only set one answer as default in all of these, so I do add an exception for more than one values for point 2, are you talking about pre-filled questionnaire responses for widgets with multiple initial values? or is it something else? Thanks

joiskash commented 3 years ago

Great points @jingtang10 sorry I missed out on it.

  1. So according to the standard there are 2 rules that we need to worry about

Initial values can't be specified for groups or display items | (type!='group' and type!='display') or initial.empty()

Can only have multiple initial values for repeating items | repeats=true or initial.count() <= 1

@MuhammadSalman-7214 maybe it might be great if you add these conditions in the view model and also test them with unit tests. Basically if a questionnaire.item.type == 'group' then throw a IllegalArgumentException with appropriate error message. You can open a PR and I can quickly review it.

  1. It plays fine with prefilled questionnaires. I ran the code on my local system and tried it out. This is because the prefilling condition is a different else block in which createQuestionnaireResponseItem is not called.
MuhammadSalman-7214 commented 3 years ago

@joiskash sure, let me test it on my end, and then after verifying, I'll show you the check and then will write the test cases

jingtang10 commented 3 years ago
  1. It plays fine with prefilled questionnaires. I ran the code on my local system and tried it out. This is because the prefilling condition is a different else block in which createQuestionnaireResponseItem is not called.

Thanks @joiskash!

Is this the expected behavior for questionnaire response? For example, you have a questionnaire with some initial values, you also have a questionnaire response, if a particular question doesn't have an answer in the response, but has an initial value defined in the questionnaire, should we leave that question empty?

To me, this seems right. But I don't know the use cases too well.

Might be worth adding a unit test if we want to do this?

MuhammadSalman-7214 commented 3 years ago

If a particular question doesn't have an answer in the response, but has an initial value defined in the questionnaire, should we leave that question empty?

@jingtang10 haven't got it, now we are setting the questionnare response if we have initial value no matter whether user changes or not, then how that question will be empty? Can you please explain this? thanks

joiskash commented 3 years ago
  1. It plays fine with prefilled questionnaires. I ran the code on my local system and tried it out. This is because the prefilling condition is a different else block in which createQuestionnaireResponseItem is not called.

Thanks @joiskash!

Is this the expected behavior for questionnaire response? For example, you have a questionnaire with some initial values, you also have a questionnaire response, if a particular question doesn't have an answer in the response, but has an initial value defined in the questionnaire, should we leave that question empty?

To me, this seems right. But I don't know the use cases too well.

Might be worth adding a unit test if we want to do this?

Well I guess the required field will also play a role in this. I am not too sure of the answer. We should probably ask the larger group.

But I agree to adding a unit test to make sure the behavior is as expected. i.e. the UI will be empty. Because if the Questionnaire response has been generated using the SDC library then the questionnaire response will by default have the initial value. So the condition question.item.initial.notEmpty() and questionnaireResponse.item.answer[0].empty() will happen only if the questionnaire response is externally generated.

joiskash commented 3 years ago

@jingtang10 haven't got it, now we are setting the questionnare response if we have initial value no matter whether user changes or not, then how that question will be empty? Can you please explain this? thanks

@MuhammadSalman-7214 what he means is that when we pass a questionnaire response to the fragment, the UI is automatically filled with the answers. Now if we have a questionnaire.item = "Where are you from?" with questionnaire.initial = "Kathamandu" but the corresponding questionnaireResponse.item is empty then should the UI be empty or should it have the initial value?

Currently the UI will be empty . We need to make sure that this is intentionally done and there is a test to verify it.

MuhammadSalman-7214 commented 3 years ago

@joiskash, but why the UI will be empty? once we set the initial value, then it is rendered to the UI and on response as well. It's up to the user whether he wants to change it or not.

joiskash commented 3 years ago

If you have noticed, there are two ways of using the SDK. One is by passing only a questionnaire to the fragment and the other is by passing a quesitonnaire and a corresponding questionnaire reponse(with answers) we are talking about the second use case. If you look at the view model, in the second init block you will see an if condition. This is where the different behaviors for the two modes are established.

I would suggest running the prefilled questionnaire example for the neonatal quesitonnaire. Debug it and you will understand in more detail. This example is the last example in the list of examples in the gallery application.

MuhammadSalman-7214 commented 3 years ago

okay thanks

MuhammadSalman-7214 commented 3 years ago

@joiskash and @jingtang10 I have added the test case for the above case when there is Initial value, but no corresponding Response Value in my latest push https://github.com/google/android-fhir/pull/417/ to verify the case. We can either set response as empty, or cannot set at all if the Question type is GROUP. You guys can check that. Thanks