Skip to content

Multi Select Case Lists

Shubham Goyal edited this page May 20, 2022 · 5 revisions

Multi-Select Case List

Multi-Select case lists are case lists that allows user to choose multiple cases on the case list at once. This document outlines the fundamentals for someone looking to dive into implementation details for these case lists.

Instance Datum

Multi-Select case lists are backed by a special kind of datum called 'instance-datum'. These datums are specified under entry definitions like a normal 'datum'. An example of such datum is -

<entry>
    <session>
        <instance-datum id="selected_cases" nodeset="instance('casedb')/casedb/case[@case_type='case_type']" value="./@case_id" 
        detail-select="select_detail_short" 
        detail-confirm="select_detail_long"
        max-select-value=”10”/>
    </session>
</entry>

This is exactly similar as a single select datum type though might implement additional attributes like max-select-value that indicates the max number of selections allowed on the case list.

Instance datum lives as MultiSelectEntityDatum inside commcare-core and is parsed by SessionDatumParser

HTTP Lifecycle b/w Web Apps and Formplayer

When user selects multiple entities on a multi-select case list screen, Web Apps first make a navigation request to Formplayer with the selected entities ids stored with the request json -

{
   “selected_values”: [“case_id_1”, “case_id_2”],
   “selections”: [“0”,”1”, “use_selected_values”]
}

Using a placeholder like ‘use_selected_values’ allows us to delegate the ‘selected_values’ input to the right case list screen in the session in case there are multiple case list screens involved in the navigation.

In response to the above navigation request, Formplayer processes the selected_values and stores it locally against a unique guid. Formplayer conveys back this guid to Web Apps by replacing the placeholder ‘use_selected_values’ in selections[] with the guid resulting in a selections array like -

{
     “selections”: [“0”,”1”, “guid”]
}

On the next navigation request, Web Apps use the same selections[] array as base and append any next user input to it. For eg. If user selects another menu after making the selections in multi-select case list, the selections array in subsequent navigation request to FP should be -

{
     “selections”: [“0”,”1”, “guid”, “0” ]
}

Note that at this point WebApps is not required to send the ‘selected_values[]’ again as FP can reference the ‘guid’ and load the selected values locally.

Selected Cases Instance

Formplayer makes the selected cases available in the form using a selected cases data instance.The data in this instance can be referenced inside form using an XPath expression like instance(‘selected_cases’)/results/value[0]

Persistance Layer

To make the selected cases instance available during subsequent session navigation requests from Web Apps, Formplayer needs to persist the xml data for the instance. Formplayer does that by serializing and storing the xml instance into the Postgres Entity called SerializableDataInstance, the sql schema for which can be found here

SerializableDataInstance keeps a temporary record of selections made by a user against a uuid so that we don't need to paas in the selections with each client request to Formplayer and also makes it possible to have short lived restful urls corresponding to a particular selection.

VirtualDataInstanceService provides a wrapper on top of SerializableDataInstance to perform basic read and write operations for a serialized data instance.

Navigation Layer

If you are unfamiliar with Formplayer navigation, you are highly encouraged to first read through the Formplayer Navigation Basics

Multi-select case lists are represented by MultiSelectEntityScreen. MultiSelectEntityScreen is an extension of single-select EntityScreen. It does 2 main things in the multi-select context -

  1. Makes the xml instance 'selected_cases' from the selected_values input passed from Web Apps and stores it in the DB
  2. Updates the CommCare Session to add the uuid of the stored selected_values instance against the selected_cases instance.