Query parent contact place data in child form

We currently have the requirement to load previously selected location data from the parent place hierarchy contact form.
This is required since each ‘Team Area’ under the ‘NPO’ needs to define where their area of operation will be for the available selections the ‘NPO’ has been assigned to in its create form.
The ‘NPO’ form in question can be found on this thread.

In a meeting with Marc we discussed this requirement and it sounded like the intended result could be achieved via a contact-summary approach.

Unfortunately, I have very limited knowledge of how that file functions which makes it quite difficult customize it to suite our needs.

Any help in explaining it’s workings and/or example files would be greatly appreciated!

1 Like

So, if I am understanding your question correctly, in the npo-create form, you collect information about the area of operation that will apply to the child “Team Area” places. Then when you are filling out the Team Area create form, you want to be able to reference the area of operation data already collected when creating the NPO place. Is that correct?

If so, then you may not need the contact-summary at all. Contact create forms (e.g. your Team Area create form) have access to some data about the parent contact. Most importantly is the parent value which has the id of the parent contact (in your case the NPO). You should be able to use that value with the contact selector functionality to then load data from the parent contact into the form. So, as long the area of operations data is stored on the NPO contact doc, you should be able to load it like this!

Contact summaries are more useful for compiling data about a contact that changes over time (and so cannot just be set when creating the contact). Contact summaries can define three related things:

  • You can add additional fields to be displayed in a contact’s profile
  • You can add condition cards which are special content boxes in a contact’s profile to show information about something related to the contact
  • You can define data on the contact summary to provide as context for the app forms (contact-summary data is not accessible from contact forms)

The third use case is the one that is most relevant here. However it is most useful if you want to share context between app forms and it is not really applicable for contact forms. For the record, though, a good realistic example of using a contact summary is the one for pregnancy in the default config. Among other things, that config sets the pregnancy_uuid value in the contact-summary context when a new pregnancy report is submitted for the contact. Subsequent forms for that patient can then reference the pregnancy data for the patient using that pregnancy_uuid value (e.g. the pregnancy_danger_sign_follow_up form).

Yes that’s spot on!

That’s fantastic news, thank you so much for the explanation.
I have, unfortunately, been unable to retrieve data using the parent grouping in the input group.
Though I have noticed on our Team Area form there is PARENT variable being referenced, which seems to contain the required id. It seems to function the same way PLACE_TYPE does.
Could you perhaps provide more info regarding this?
I’m unsure how to use this retrieved id in conjunction with the contact selector in order to retrieve the desired parent form data.

In addition to just retrieving the location information, we need to make those values available in 3 drop downs - similar to how it’s displayed on the NPO forms.
We’ve only seen examples of select_one and select_multiple getting their data from the choices sheet.
Is it possible to rather reference a dynamic data list?

Thank you so much for the detailed explanation! If I understood that correctly, one could then be used in order to draw the most recent data from multiple surveys to construct a sort of “cheat sheet” as mentioned in other question.
I’ll be sure to have another look through the pregnancy example, thank you for pointing that out.

Whoops! Reading that linked documentation again, I can see that there are a few gaps that make it very confusion for this particular use case. Sorry!

I will work on getting that documentation updated, but in the meantime, here is some sample config that you can add to your team_area-create form that should allow you to load npo data (so far all I have included is the name field):

type name label::en appearance calculation
begin_group npo_data NO_LABEL field-list hidden
string _id NO_LABEL select-contact type-npo …/…/PLACE_TYPE/parent
string name NO_LABEL

Basically, just add this group at the top level and you should be able to reference the name of the NPO by using the name field in other expressions. (In practice, you will probably want to nest this group in a different one, such as inputs or else it will cause an empty page to show in the form. Just make sure to adjust the path in the _id calculation when you do that.)

As you noted, in the team_area-create form, the PLACE_TYPE/parent field will contain the id for the NPO. The select-contact functionality will map any of the data from the NPO’s contact doc into fields in the npo_data group. To load more of the data into the form, simply add fields/groups to the npo_data group with matching names.

Is it possible to rather reference a dynamic data list?

So, I do not think it is possible to populate a select question with completely dynamic data that is not on the choices sheet. What you should be able to do, though, is filter the choices available on the Team Area form based on what was selected on the NPO form.

type name label calculation choice_filter
calculate main_places_options “redmond tacoma”
select_one main_places main_place_selected Select Main Place selected(${main_places_options}, name)

This is a simplified example where I am using a hard-coded value for main_places_options, but imagine that value is loaded from the NPO. You can use the selected function in the choice_filter and then filter on name so that the only main places that can be selected are ones that exist in main_place_options.

It is no problem! Thank you for taking the time to explain the steps in satisfying our use case, especially in such detail.
It really is greatly appreciated!

We’ve implemented your sample config and it has produced our required output :partying_face: , thank you so much. Please see the file here.

We did unfortunately run into a bit of an issue, where if the npo_data group is moved within the inputs block it no longer produces any values.
And, as you’ve mentioned, leaving it on the top level causes a blank page to be rendered even with the field-list hidden property being set.
I’m a tad bit confused by this behavior, would you perhaps be able to provide some clarity regarding this?

Your selected solution worked like a charm! We’re so relieved to hear that there’s an xlsx form way to address this requirement, as originally a ODK thread suggested editing the xml in order to access those dynamic values (I will edit this post once I find the link again).

For the life of me I was unable to get the choice_filter to work with both the “cascade” district and the selected(${...}, name) function, in a single drop down. Not sure if I’m doing something wrong.
So I’ve implemented a little workaround where the relevant drop down is duplicated.
The first drop down contains the calculated values of the prior NPO selections, as well as the relevant level choice_filter (eg. district=${district}).
The second drop down then uses the first drop down as a selected choice_filter.
It’s not ideal, seems to work though. Unsure how to better it at this time, any thoughts?

Another thing we have noticed while testing is that when there are a few ‘NPO’ items already created, and we’ve selected one of them in order to create a ‘Team Area’, we sometimes forget which NPO we are using for the test.
And, please do correct me if I’m wrong, there does not seem to be any visual indicator whilst in the contact create or edit flow.
So we attempted to create a sort of “breadcrumb” calculated value, that could be referenced in the form_title (since it is displayed at the top of the whole form flow).
Unfortunately, that does not seem to work. Is there a way to do something like that?
So as an example:
For the hierarchy of “NPO1”, “Team Area1”, “Indawo1”.
In the “Bounded Structure” create form, which sits underneath the Indawo level, we would like to display the title of something like “create new NPO1>TeamArea1>Indawo> Bounded structure”.

This also ties in with the issue of placing the npo_data in the inputs block, as I’ve read that this is how the data of a parent of a parent is accessed. Unsure if we can already accomplish this with a similar npo_data type of approach?

1 Like

if the npo_data group is moved within the inputs block it no longer produces any values.

Ah, sorry, I think this is my fault again! After tinkering with this some more, it appears there are some surprising consequences to putting the contact selector in the inputs group.

I have ended up logging the following:

The current workaround is just to nest the npo_data group into an existing page and include the hidden appearance on any of the fields you do not want to see on that page.

I was unable to get the choice_filter to work with both the “cascade” district and the selected(${...}, name) function, in a single drop down.

Hmm, I am not sure if I am missing something here, but I seemed to see the same (correct, I think) behavior when I updated the sm_municipalities choice_filter to be selected(${ext_values}, name) without the sm_municipalities_initial field. Is there another dimention that I am missing here? (I think ext_values is already specific to the district right?)

there does not seem to be any visual indicator whilst in the contact create or edit flow

This is correct. I don’t know think there is any “built-in” way to get a breadcrumb like this when filling out a form. You should be able to use the contact selector functionality to retrieve several layers of hierarchy and then manually create a breadcrumb in the label of each field-list group. This would be a good topic to raise for discussion over in Feature Requests - Community Health Toolkit. One reason folks might not want to see a breadcrumb like this is just to keep the data-density displayed in the form to a minimum. But raising the discussion could help us understand if this is a feature the broader community would consider useful!

Also, I am not sure how relevant this is to your situation, but it seems like a lot of the logic we are looking at here is concerned with being able to define the hierarchy structure of the places from the top down based on data provided when creating the NPO. In my experience, place hierarchy typically only changes infrequently (and incrementally) after the initial deployment. If you have not yet, it might be worth checking out the Bulk User Load functionality that can be used to create a contact hierarchy (complete with users) all in one go! Avoiding having to build out the whole hierarchy by manually filling out contact forms may reduce challenges like the one you mentioned about forgetting which NPO is in context…

It is no problem! Thank you for taking the time to look into this and opening the linked Github issues.

As suggested, I’ve implemented the workaround and achieved the desired results :partying_face:.

One interesting finding is on the first attempt the npo_data group was placed within the init group of the Team Area file.
Since the init group is responsible for deciding if a contact should be added or not, and then displaying the new contact content if so - when the npo_data is also placed within that group it no longer shows the contact content.
Moving the npo_data to the begin group fixed the issue, and no longer produces an empty page, just thought that was an interesting occurrence.
The new file can be found here (data persistence is still a WIP).

That’s a good point, I think you’re correct. Thank you for pointing that out, we’ll get that sorted.
I’ll attach the updated form to this post thereafter.

— Edit —

As promised the newest Team Area create form and Team Area edit form.

Thank you for the suggestion, we’ll give it a go and see if we can achieve the desired results.
Would I be correct in assuming that one just creates multiple nested groups (one for each parent level) with a field named _id in order to load the required parent.
Though at the moment we’re using the parent variable to access the immediate parent id, as the inputs approach did not work as expected. How would we then access the subsequent higher level parent ids?
Thank you for the suggestion on opening a feature request, you make a valid point, the screen availability on mobile devices would also be quite sparse. I’ll think on it a bit.

You’re absolutely correct, and that’s a very valid point!
We will definitely have look into the bulk loading of users for our on boarding needs, thank you for the link.
Working through the forms for the places hierarchy (NPO > Team Area > Indawo > Dwelling > Household) has helped us identify information we would like to see, and what is required, and in so doing refine the relevant documentation (especially since this is a re-platforming endeavor we’re trying to reduce the amount of “noise fields”).
This in turn will also help us identify what fields we care about to include into the CSVs for bulk loading.
We also have to facilitate household members moving around quite a bit, and households themselves splitting into smaller entities or disbanding.

I digress. I’ll be sure to raise this point with the team, then we can consider shifting our approach - especially with deadlines being what they are.


Happy to help clear some things up here! And I just want to say, @robinmurphy, that your high-fidelity feedback and followup is super helpful! ODK forms are so open-ended that it can be hard to understand when some complex configs are working like we expect or not. So, thank you for that!

How would we then access the subsequent higher level parent ids?

Your contact docs should each contain de-normalized parent id values going up three levels in the place hierarchy. To get more data about any of these levels, (e.g. to get the names) you can apply the select-contact appearance to load the data for that contact doc directly into the group containing the _id value. For example, this should load the names of the three levels above the contact in the hierarchy:

type name label::en appearance calculation
begin group parent_data Parent data
string _id Parent ID select-contact …/…/…/PLACE_TYPE/parent
string name Parent Name
begin group parent Grandparent data
string _id Grandparent ID select-contact
string name Grandparent Name
begin group parent Great Grandparent data
string _id Great Grandparent ID select-contact
string name Great Grandparent Name
end group parent
end group parent
end group parent_data

(For performance reasons, you should also include the proper type-? appearance with each of these select-contact fields.)

Note that your user will only be able to load data from docs they have access too. So, if the user cannot actually see the great-grandparent contact, they will not be able to load the name of that contact into a form.


Thank you for your kind words, and you’re most welcome, glad we could be of service! You have been absolutely instrumental in helping us achieve the results we require! We really do appreciate your patience and all you’ve done to assist us.
A huge thank you to you, and the team at large. - Robin/Anro

Thank you for the detailed multi level parent example, we will definitely leverage this in the lower level place hierarchy items!
Also appreciate making a point of the type-? optimization suggestion and the “they have access too” caveat, we’ll be sure to take note of this!
We’ll be sure to edit this post when we have a working example :slight_smile: