Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

...

We have several different tools for controlling what is seen during

...

menu navigation in CommCare (everything between the Start screen and the Form itself). This page should help clarify the different options available.  

Table of Contents
stylenone

Menu Navigation

...

There are three key things that control which screens show up during the menu navigation:

...

The controls for these are outlined in red in the first 3 of the following screenshots:

To turn on menu mode, make sure the "Menu Mode" Add-Ons is enabled on the application settings page.

  1. Access the Application Settings page by clicking the gear icon next to the application name on the upper-left corner. 

  2. On the settings page, select the Add-Ons  tab, then select the button with three-lines in the upper right hand corner and make sure the Mobile Experience is checked.

  3. Scroll down to the Mobile Experience block and select the Register from case list checkbox and hit save.

...

  1. ♣ Menu Filter (Case List Menu > Settings tab)

  2. ♥ Form Display Condition (Form Settings > settings tab)

  3. ♦ Case List Filter (Case List Menu > Case List tab)

...

  1. ♣ Menu Filters:  You You will notice that Menu filters are always applied before a case has been selected.  Therefore, they cannot depend on any of the case properties associated with the case.  Menu filters can only be used to filter on properties from the user-case or on constants, such as false().

  2. ♥ Form Display Conditions:  

    1. For paths 1.a.i and 2.a.i above, the Form Display Condition is executed after a case has already been selected from the case list.  Therefore, the Form Display Condition can depend on the case properties, any user-case properties, or on constants, such as false().

    2. (warning) For paths 1.a.ii and 2.a.ii above, the Form Display Condition is executed before any case has been selected from the case list.  Therefore, the Form Display Condition cannot depend on any regular case properties.  In these paths, the display condition can only be used to filter on properties from the user-case or on constants, such as false().  If the application is not using user-case, the Form Display Condition will not be available at all.  The (warning) symbol should alert you that Form Display Conditions are limited in these paths and you should be careful to understand these limitations before using one.

    3. Form display conditions are not currently available when Menu Mode = Display Only Forms. 

  3. ♦ Case List Filter:  Case list filters are always available to filter the case list.

See https://dimagi.atlassian.net/wiki/x/OinKfw for more information about the User-Case feature referenced above.

CommCare allows you to intelligently filter menus in your application based on standard XPath Expressions. This article walks through filtering menus, but filters can also be used on individual questions

1… To enable menu filtering, you first need to enable the Display Conditions add-on. Select the gear icon next to the application name in the upper left hand corner. Then select the Add-Ons tab.

...

2. Select the three lines on the right hand side and select the 'Calculations' option if it is not already displayed.

...

3. Now enable the "Display Condition" add-on. Be sure to save after enabling the feature:

...

Menu filters are added on the Menu Settings page:

...

Expressions are written using a standard XPath Expression. You can find examples of these on the Common Logic and Calculations and CommCare Functions.

Note that you must change your CommCare version to 2.20 or later in the Application Settings AND you must be using CommCare mobile 2.20 or later in order to use a Menu Filter.

You may want to temporarily hide a menu in a deployed version of an app. In order to do this you can simply use: "false()"

Menu filters can reference Custom User Data, so you can create an XPath expression that registers a particular user property. For example if your users for which the user data type is supervisor you could create the following XPath expression:

count(#session/user/data/type) > 0 and (#session/user/data/type= 'supervisor')

Another example is when you want to use your app in several countries and only show specific content to users from each country. For example when deploying an app to India, Senegal, and Zamba, the user property country would be set to either India, Senegal, or Zambia for each user. If I want to show the module to users from only Senegal and Zambia I would create the following XPath expression:

count(#session/user/data/country) > 0 and (#session/user/data/country = 'Senegal' or #session/user/data/country= 'Zambia')

There are certain situations that make it more challenging to navigate through an application. For example: selecting a parent case, filling out a form for the parent, selecting a child case and filling out a form for that child. Typically a scenario like this requires navigating to each form from the app's home screen and selecting the parent case selection twice.

The navigation can be simplified by using Sub Menus to nest one menu inside of another menu. In the above example, this would allow the child case menu to be nested within the parent menu. This nesting is seen by mobile workers when navigating through the app. In regular workflows, only forms can be found after selecting a menu. When using Sub Menus, an app builder can place other menus under a parent, alongside forms.

In order to use Sub Menus you must enable the Add-Ons under app settings:

...

If you don't see the Sub Menu setting under the Add-ons app settings, go to the menu in the top right corner, and select "Mobile Experience":

...

Once you have your menus configured you can set the parent on the menu settings page:

...

After creating a parent/sub menu relationship, the sub menu(s) will appear nested under the parent menu in the form tree:

...

Here, the Children menu is a sub menu to Mother Registration and appears indented and connected to its parent menu with a thin line. Sub menus will always appear beneath their parent, even if they were originally positioned elsewhere in the form tree's hierarchy. If a parent menu has a number of sub menus, they will all appear nested under the parent. However, sub menus can be rearranged as needed.

If you need to delete a parent menu, you must first decouple its sub menus. You can do so by navigating to the sub menu's settings page and choosing 'No Parent' in the Parent Menu field, or by simply deleting the sub menu first.

Sub Menus can be combined with the Menu Mode add on to further customize your apps workflow. When enabled, Menu Mode allows you to choose between two workflows: first, if 'Display menu and then forms' is selected, the mobile worker must first choose the menu and then the form(s) under it. If 'Display only forms' is selected, the icon for the sub menu with this setting defined is not displayed, and its forms are displayed in its place. The latter workflow would allow mobile workers to directly select forms from the sub menu, provided the case type is the same between parent menu and sub menu.

...

More about Add-Ons can be found at https://dimagi.atlassian.net/wiki/x/lArKfw.

If your sub menu contains a form that updates cases and you want the child case list to only show child cases of the selected case in the parent menu's case list then you must configure the child menu as such on the Case List page:

...

Parent child case selection and forms

This is the common use case where the user has configured two menus: M1 (case type = mother) and M2 (case type = baby). M2 is configured with parent selection (making the ‘baby’ case type a child of the ‘mother’ case type).

The user now selects M1 as the parent menu of M2.

Result

Only M1 is shown in the app’s home screen. After selecting M1 and selecting a ‘mother’ case the user is presented with the M1 forms and also the menu item for M2. Selecting M2 will prompt the user to select a ‘baby' case that is a child of the previously selected 'mother' case. Then M2 forms will be displayed.

  • A sub menu has a different case type from its parent and the case types are not related i.e. not parent / child cases.

  • Multiple levels of nesting.

  • Form in parent menu does not update case.

  • Registration from child menu's case list isn't supported.

  • Drag & drop functionality to create a parent/child relationship.

  • End of form navigation from one child form to another child form within the same menu. A workaround would be to create a separate child case type case list with the other child form, and have the end of form navigation point to the form within this new child case list.

Form Navigation

Form Display Conditions—also known as Form Filtering or Form Display Logic—are used to filter the content of your CommCare application for a specific use case.

Please see Display Conditions Overview for more information.

...

Use Form Display Conditions when you have a form that you only want available to a specific group of users or cases. When you put a display condition on a form, it is only accessible on CommCare Mobile when a given user or case matches criteria you've previously defined.

For example:

  • you have a form that you want to be available only to certain types of users (in this workflow, you'll use user properties, rather than case properties, as your filter) 

  • you have a form that is only relevant to patients with a positive test result.

  • you have two versions of a form - one for children under one year of age, and one for all other children- and you want to make sure the user only chooses the correct form.

You first need to turn on the Add-Ons for Display Conditions in your application. 

  • On the form's settings page, outside of the Form Builder, you can specify a display condition.  The display condition determines whether or not the form shows up in the form menu.  

  • You can view this field by selecting the button with three-bars in the top right hand corner and selecting to display the 'Logic' field

...

  • For this to work, the user must select the case BEFORE filling out the form.  This means that the "Menu Mode" setting on the module must be set to "Display module and then forms", and every form in the module must require a case.

  • It accepts the same kind of logical expressions as the Form Builder (see sections above), EXCEPT you must add ./ before any case property name. (For example, in Form Builder, you’d reference something as /data/edd. Here, it would simply be ./edd)

  • For example, write the following to say the expected delivery date (property name "edd") must be within the next week:  today() - ./edd <= 7

  • You can also refer to properties of some special cases too.

    • Use "#user" to refer to user case properties. e.g. #user/experience_level > 3

      • If a user does not have a value for the case property, you will see an error that says: "Logic references instance(commcaresession)/session/user/data/(...) which is not a valid question or value".

      • In order to avoid this, add an if() statement to check whether the case property exists first. For example:

        • if(count(instance('commcaresession')/session/user/data/USER_PROPERTY) > 0), instance('commcaresession')/session/user/data/USER_PROPERTY = 1, 0)

    • Use "#parent" to refer to the parent case of a child case. e.g. date(#parent/dob) >= date('1997-01-01')

    • Use "#host" to refer to the host case of an extension case. e.g. #host/suburb = #user/suburb

  • Referencing lookup tables on a form display condition uses a slightly different syntax than in app-builder. Here are some examples :

    •  instance('item-list:country')/country_list/country/id != "kenya"

    • instance('item-list:user_permissions')/user_permissions_list/user_permissions[user_role=#session/user/data/user_role]/f_register_household = '1')

Sometimes you only want a form to be filled out one time for a case. The definitive way to do this is to use case management and form filtering, such that the form is only available until it has been filled out once.

First, you have to make sure that the form is in a module that only has forms that require a case. This means that there cannot be any registration forms in the module. That way the case list will display before the form list. Let's take an example where you have a Literacy Test form that you only want to fill out once for each of the pregnant women that you are monitoring in your app.

Set up the form:

  • In the Literacy Test form you will create a hidden value called something like literacy_form_complete

  • Set the calculate condition to be contain some text or number- for example, we could set the calculate condition to "complete"

  • In the form case management, save literacy_form_complete as a case property

...

Now you will need to set up a Form Display Condition for the Literacy Test form. Set the display condition so that the form only is displayed if literacy_form_complete DOES NOT equal complete. It would look like

./literacy_form_complete != 'complete' 

For each new case the literacy_form_complete property will be empty, so the form will be displayed. But whenever the Literacy Form is filled out for a case, the case property value will change to "complete" and the form's display condition will never be met.

Sometimes there are a number of different forms for a case and you want only one to be filled out at a time. You can set up an application so that at first it only shows "Home Visit 1" and then after that so it only shows "Home Visit 2," etc.

The basic structure is very similar to the instructions above for making a form disappear, and again this will only work in a module where all forms require a case (this allows the case list to show up before the form list)

Set up your forms:

  • In each form create a case property called next_form

  • Set the calculate condition in each form to be the name of the subsequent form you want to display, or a number for that form. For example, in Home Visit 1 the value of next_form will be "2" and in Home Visit 2 the value of next_form will be "3"

  • In the form case management make sure to save next_form as a case property in all forms

Set a Form Display Conditions for each form that references the value of next_form. The display condition for Home Visit 1 would be ./next_form = '' or ./next_form = '1' (at first the case property next_form will be empty, and that is when we want to show Home Visit 1) and for Home Visit 2 it would be ./next_form = '2'.

To complicate this workflow a bit, suppose you have a form in the list that should only appear if certain conditions are met.  In that case, you can update the hidden value which updates the case property next form based on which form should appear next.  For example, let's say you only want display home visit 2 if the home being visited has a front yard, if not you'll want to skip firstly to the form Home Visit 3.  Your question (#form/front_yard) would be:

Does this home you're visiting have a front yard

a) 'yes'

b) 'no'

Then the hidden value which updates the case properties would then calculate to - #form/next_form = if(#case/front_yard = 'yes, '2', '3').

One thing to consider about these workflows is that they are very inflexible. So if for some reason a form needs to be filled out again, it is not going to be possible without having forms able to affect the next_form property in more complicated ways.

A solution to this is to have a 'reset forms' form which is always visible within the module.  This form can contain just one single-select question and each choice should correspond to a form in the list.  The value of each choice should correspond to the number of the form represented.

Eg - Which form would you like to reset to?

           a) Home Visit 1

           b) Home Visit 2

The value for choice a would be '1' and the value for choice b would be '2'.  The answer to this question should then update the case property next_form.

Each form will have a unique form export available in the data export tab on CommCareHQ. Although you may be have multiple forms in an application, form filtering will hide these based on the display logic. As a result, form submissions will only display for the forms that were actually submitted.

For example – Let’s say you have three forms all named “Child Form”, but you use form filtering to divide this for children <1 year, 1-2 years, and 2-3 years. Although on the mobile it may appear as only on form, using form exports, this will display as 3 unique forms, and the form submission will display for its respective forms. 

Case management allows you to save data from one form and use that data later on in another form.  Here's how to set this up:

Say you want to use the answer to "What is your edd?" in Registration later on in your Followup form.

  1. Set up case management in your application.

  2. Create a question in Registration for "What is your edd?".  It doesn't matter what the question ID is.

  3. Go to the Case Management for the Registration form:

    1. Select "What is your edd?" from the dropdown

    2. Write "edd" in the case property box.  

    3. Hit "save". The answer to "What is your edd" is now saved to the case as case property "edd"

  4. In the followup form, reference that case property by typing #case/ and choosing the property you want to reference

NOTE:  When data get saved to the case as properties, they're always saved as text.  If you reference them in a form, even if you set the data type to be "date" or "int" or whatever is appropriate, they're still really strings. If you want to use it in a calculate or a comparison expression, you have to "cast" it to the desired data type.  For example, if you reference a property into the hidden value "date_question", you have to reference it as date(#case/date_question).  Other available cast operators are int(), boolean(), number() and string().  

When you build your CommCare application, you can define the screen that will direct users after they submit a form instead of returning to the home screen. This feature is called End of Form Navigation, and it offers four options for users to choose from, depending on the application configuration: Home Screen, First Menu, Previous Screen, and Link to another form or menu.

Here's an overview of each option:

  • Home Screen: This takes the user to the start screen on Android or the module list on feature phones.

  • First Menu: The user will be directed to the module menu within the application they are working on.

  • Menu: If the user selects this option, the screen they would see when clicking on a module name will be displayed. 

    • If the application is configured such that the case list comes before the form list, this will take the user to the case list. 

    • If the application is configured such that the form list comes before the case list, this will take the user to the form list. However, if the menu mode of the module is set to "Display only forms," the user will be returned to the home screen, not the module screen.

    • Previous Screen: This option returns the user to the last screen before the form was opened. Depending on the application's configurations, this could be a case details screen, a form list, or a child case list.

  • Link to other form or menu:  This allows for conditionally linking another form or menu, which we'll call target. This means when the user submits a form, let's refer to this as the source form, another screen in the app will be automatically loaded.

...

Below are the steps to configure the end of form navigation:

Step-1: While editing your form, select the option to manage a case. 

...

Step-2: Activate the option to show the logic, allowing you to configure the end of form navigation..

...

Step-3: Select the desired option from the menu.

...

If you select "Link to another form or menu" you will need to specify a target form and may need to set up a conditional expression to determine whether the form should be presented to the user. Here's how:

...

Target Form - Specify the form that will open once the user submits the current form.

Linking Data - If the target form is located in a module that caters to a different case type than the current form, you may need to specify the case_id of the case that Commcare will need to load. In most scenarios, if the case_id is the same as the current form, Commcare can manage this independently, and no user intervention is required.

Conditional expression -If the decision to link to the target form is dependent on a condition being met, you will need to specify a conditional expression. This expression must return a boolean value (true or false). Note that in the context of the form link conditional expression, form content is unavailable, so the expression must rely solely on case properties.

In the context of the form link conditional expression, form content is not available, so something like /data/some_question=’yes’ wouldn’t work. The expression below is an example of a expression that could be accepted if the property link_form is saved to the case. This expression gets the case from the case database (casedb), based on the ID stored in the user session, and verifies whether the property link_form is equal to ‘Yes’. If the expression returns 'true', the target form will be presented to the user, otherwise Commcare will move to the next condition, if applicable, or fallback to one of the default options.

...

Navigation fallback - select where the user should navigate to if that form is not available (for example, if the form is hidden for that case, if the form is hidden for that user, or if the the data needed for the form to open has not been provided). For example, let's say there's a registration form that links to a follow-up form right after it. But only supervisor can do follow-up. If there is a display condition that hides the follow-up form form the normal user and the normal user finishes a registration form, CommCare can’t follow through with the end of form navigation, so it sill fall back on any menu or page you specified in the Navigation Fallback setting. If a supervisor finishes a registration, the form is accessible and end of form navigation happens.

Note: The Case ID is not always referenced in the session as case_id, this varies depending on the form and module configurations. 

Panel
panelIconIdatlassian-info
panelIcon:info:
bgColor#EAE6FF

Form linking is conditional on a case property being met, the XPath Expression must reference the specific case from the casedb.

  • The default XPath reference to a case_id that's been loaded into a form context is instance('commcaresession')/session/data/case_id. You can reference case properties from this case by using the following example syntax:

    • instance('casedb')/casedb/case[@case_id = instance('commcaresession')/session/data/case_id]/link_form = 'yes'

  • It's possible to load multiple cases into the same form. This means that there is no default syntax for referencing these cases. To see what data exists in your session hash, you can: 1) Go to App Preview, 2) Open the form you're linking from, 3) Click on "Menu" and select "Evaluate XPath", 4) Type instance('commcaresession')/session. This will display all the data that you can reference from the session hash. See the following example syntax:

    • instance('casedb')/casedb/case[@case_id = instance('commcaresession')/session/data/case_id_new_qi_report_0]/next_step = 'indicateurs'

There are some limitations to End of Form Navigation:

  • Menus and Linking Data - Menus typically do not require data. The few that do, like menus with a parent menu, do not allow you to customize what data is passed. Even more rarely, a menu may not be available because it requires data, and HQ cannot determine what data it needs. This is likely to happen only with parent-child menu workflows that use different case types than the form you're linking from.

  • Registration from the Case List - It is not recommended to set up End of Form Navigation anywhere except the home screen for forms being used as Case List Registration forms. This can lead to unexpected behavior in the Case List Registration workflow. However, despite the warning message displayed when form linking is attempted, it can still work for most use cases. Just make sure to thoroughly test it on Formplayer and mobile.

...

Display Only Forms - If you're linking to a menu, not a form, the menu cannot use the display-only forms setting. This is because these menus do not have their own dedicated "screen," and their forms are displayed in the home screen or their parent menu's screen (if there is a parent).

...

.