Vibha's data and monitoring platform · vibha.org

Cascading and lookups

You have seen this everywhere online: pick a country, and the “state” dropdown next to it suddenly only shows states in that country. Pick a state, and the “city” dropdown narrows again. That behaviour — one dropdown filtering another — is called a cascade, and here it takes two dropdown lists and a small setting to build, once, rather than being wired into any one form by hand.

The problem in plain terms

Without a cascade, a “District” dropdown with 766 entries in it is genuinely unpleasant to use on a phone in the field — scrolling through districts from every state in the country to find the three that belong to Andhra Pradesh. And nothing stops someone from accidentally picking a district from the wrong state entirely, since the dropdown has no idea which state was already chosen.

A cascade fixes both problems at once: choosing a state first narrows the district dropdown down to only the districts that actually belong to it. Fewer items to scroll through, and no way to end up with a mismatched pair.

A real-world example first

Say a field team fills in a monitoring visit form that needs to record exactly which school they visited. Typing “District”, then “Block”, then “School” as three separate dropdowns, cascading one into the next, means: picking “Visakhapatnam” as the district instantly narrows Block down to only Visakhapatnam's blocks, and picking a block narrows School down to only that block's schools. The respondent never even sees the roughly 40,000 other schools in the country that are irrelevant to them.

District

Select an option · dropdown list: districts

Block

Select an option · cascades from District

Cascading

School

Select an option · cascades from Block

Cascading

Nothing about this is specific to one form, either. Build the cascade once, on the lists themselves, and every form in the organization that asks for a district and a school gets the same narrowing behaviour automatically.

Building it, step by step

  1. 1Create the parent list first — in-states, say — and get its items uploaded. This has to exist before you can point a child list at it.
  2. 2Create the child list (districts) and, in Parent list, choose the parent list you just made. See Dropdown lists for the create-a-list steps in full.
  3. 3Upload the child's items with a parent valuecolumn included. Every row has to say which parent item it belongs under — using the parent's value (its stored code, like AP), not its label (“Andhra Pradesh”).
  4. 4Back in the form builder, bind one question to the parent list, and a second question to the child list. On the child question's settings, a new option appears asking which earlier question supplies its parent answer — pick the first question you just set up.

Here is what that last step looks like inside a question's settings, once it is pointed at a list that has a parent:

Type your own optionsChoose from a list
Which listDistricts · platform · 766 items
Narrow down by an earlier answerDistrictThis list narrows down based on States. Choosing District here means the district dropdown only shows entries under whichever state was picked.

What a respondent actually experiences

SituationWhat they see
Parent not answered yetThe child dropdown says something like "Choose District first" instead of just sitting there empty. An empty dropdown with no explanation is confusing — is it broken, still loading, or genuinely empty? Saying what to do first removes all doubt.
Parent answeredThe child dropdown loads, showing only the items that belong under that parent.
Parent changed after the factThe child dropdown reloads and clears whatever was previously chosen in it — a block that belonged to the old district would otherwise be left selected under a newly picked one, a mismatched pair the system would reject when the form is submitted anyway.
A very long child listPast roughly thirty options, the dropdown becomes a search box instead — the respondent types a few letters and the matching options are fetched as they go, so a school registry with tens of thousands of entries is never all sent to their phone at once.

How deep can this go?

Cascades can chain further than two levels — state → district → block → school is a normal four-level chain. Each list only ever names one direct parent, which is exactly what a dependent dropdown needs to work. A list is not allowed to be its own ancestor somewhere further up the chain — that would make the system chase its own tail forever trying to work out what the top of the chain is — so that case is refused the moment you try to set it.

A list that other lists cascade from cannot be deleted while they still depend on it. Detach the children from it first; deleting it out from under them would otherwise make every one of those child lists — and every question bound to them — silently stop working.

Lookups: filling in a field automatically

Cascading narrows down what a respondent picks. A lookup goes one step further and fills in an entirely different field automatically based on what they picked — no second dropdown, nothing for them to type or copy by hand.

The everyday example: your school list carries a UDISE code as an extra column alongside each school's name. Add a read-only “UDISE code” question to the form, and attach a calculate rule to it that looks the code up from whichever school was chosen. The instant a respondent picks a school, the correct code appears next to it on its own — there is no way for the two to end up disagreeing, because one is derived directly from the other.

lookup("schools", school, "udise_code")

Reads the udise_code column carried alongside whichever school item was chosen for the "school" question, and fills it into this field automatically.

Anything scalar can ride along this way — a pincode, a category, a designation, a phone number. Declare the extra columns on the list when you set it up, so the rule editor can offer them to you by name, and map them again the next time you upload data.

Choosing values that will still make sense in five years

The value you assign each option is effectively a permanent ID number — every response that ever gets submitted using it points back to that exact value forever. Change it later, and every one of those old responses is left pointing at something that no longer exists. Two habits keep this from becoming a problem:

Make values stable — base them on something that will not shift, like an official code, rather than on a row number in a spreadsheet that changes the moment someone re-sorts the file alphabetically.

Make values unique across the entire list, not merely within one parent. Two different states can each have a town called Bilaspur, so a plain district value of bilaspur would collide between them — but HP-bilaspur and CG-bilaspur (state code prefixed on) never will.