|
| 1 | +# Adding choice filters in XLSForm |
| 2 | + |
| 3 | +Choice filters create dynamic forms where options in one question depend on the answer to a previous question. This streamlines data collection by presenting only relevant choices, improving survey efficiency and accuracy. |
| 4 | + |
| 5 | +Choice filters can be used for various applications, including: |
| 6 | +- **Hierarchical lists**, such as continents and countries, where the list of countries depends on the selected continent (also known as **cascading selects**). |
| 7 | +- **Removing one or multiple options from a list** if they are irrelevant for a respondent based on their previous answers. |
| 8 | +- **Reusing a list of options** in XLSForm for multiple questions, where the list varies slightly from one question to the next. |
| 9 | +- Reusing a list of options from a previous question, including **only options that were selected by the respondent.** |
| 10 | + |
| 11 | +This article explains how to add choice filters in XLSForm and includes examples for different use cases. Choice filters are defined in the `choice_filter` column of the `survey` worksheet, and operationalized in the `choices` worksheet. |
| 12 | + |
| 13 | +<p class="note"> |
| 14 | +<strong>Note:</strong> This article focuses on adding choice filters in <a href="https://support.kobotoolbox.org/getting_started_xlsform.html">XLSForm</a>. To learn about adding cascading select questions in the KoboToolbox Formbuilder, see <a href="https://support.kobotoolbox.org/cascading_select.html">Adding cascading select questions in the Formbuilder</a>. |
| 15 | +<br><br> |
| 16 | +For hands-on practice with choice filters in XLSForm, see KoboToolbox Academy’s <a href="https://academy.kobotoolbox.org/courses/xlsform-fundamentals">XLSForm Fundamentals Course</a>. |
| 17 | +</p> |
| 18 | + |
| 19 | +## Adding static choice filters |
| 20 | + |
| 21 | +**Static choice filters** apply the same filtering conditions for all respondents. When using static choice filters, a list of options is filtered, but it does not vary based on previous responses. This can be useful when you want to reuse a list of options across multiple questions in your form with minor variations, without duplicating the choice list multiple times in your `choices` worksheet. |
| 22 | + |
| 23 | +To add static choice filters in XLSForm: |
| 24 | +1. Add a `select_one` or `select_multiple` question to your XLSForm and [define your option choices](https://support.kobotoolbox.org/option_choices_xls.html) in the `choices` worksheet. |
| 25 | +2. In the `choices` worksheet, add a filter column. |
| 26 | + - You can name this column anything you choose (e.g., `q2`). |
| 27 | +3. In the filter column, write any value (e.g., `yes`) next to the choice(s) you want to include in the choice list for your question. |
| 28 | + - This value will act as the filter. It can be any word or number. |
| 29 | +4. In the `survey` worksheet, add a **choice_filter** column. This column will contain the **choice filter expression** used to filter the option choices. |
| 30 | + - The choice filter expression in its most basic form will take the format: **filter = ‘value’.** |
| 31 | + - For example, **q2 = ‘yes’** will retain all choices with **yes** in the `q2` column. |
| 32 | + |
| 33 | +### Example |
| 34 | + |
| 35 | +In the example below, the same list of choices (`activities`) is used for two different questions. For the second question, the list is filtered to show only outdoor activities. |
| 36 | + |
| 37 | +**survey worksheet** |
| 38 | + |
| 39 | +| type | name | label | choice_filter | |
| 40 | +|:-----------------|:------------------|:--------------------------------------------------------|:----------------| |
| 41 | +| select_one activities | activities | What activities do you enjoy doing in your free time? | | |
| 42 | +| select_one activities | outdoors_activities | Which of these outdoor activities are available in your city? | <strong>filter = 'outdoors'</strong> | |
| 43 | +| survey | |
| 44 | + |
| 45 | +**choices worksheet** |
| 46 | + |
| 47 | +| list_name | name | label | filter | |
| 48 | +|:-----------|:-----------|:--------------------|:---------| |
| 49 | +| activities | reading | Reading | | |
| 50 | +| activities | swimming | Swimming | outdoors | |
| 51 | +| activities | running | Running | outdoors | |
| 52 | +| activities | television | Watching television | | |
| 53 | +| activities | hiking | Hiking | outdoors | |
| 54 | +| choices | |
| 55 | + |
| 56 | +## Adding dynamic choice filters |
| 57 | + |
| 58 | +Choice filters can also be used to filter a choice list based on a previous response. In this case, you will have a **parent question** with a corresponding **parent list** of choices, and a **child question** with a corresponding **child list** of choices. The choice list for the child question is filtered based on the response to the parent question. |
| 59 | + |
| 60 | +<p class="note"> |
| 61 | +For an example of an XLSForm using dynamic choice filters, see this <a href="https://docs.google.com/spreadsheets/d/10gpBV6YaYGx1i367hyW-w1Ms9tkUQnCx0V8YsdwYxmk/edit?gid=0#gid=0">sample form</a>. |
| 62 | +</p> |
| 63 | + |
| 64 | +To add dynamic choice filters in XLSForm: |
| 65 | +1. Add the **parent** and **child question** to your XLSForm and [define their option choices](https://support.kobotoolbox.org/option_choices_xls.html) in the `choices` worksheet. |
| 66 | + - These must be `select_one` or `select_multiple` questions. |
| 67 | +2. In the `choices` worksheet, add a filter column. |
| 68 | + - It can be helpful to name this column the same as the **parent question.** |
| 69 | +3. In the filter column, enter the **name of the choice** from the parent list that each option in the child list corresponds to. |
| 70 | +4. In the `survey` worksheet, add a **choice_filter** column. This column will contain the **choice filter expression** used to filter the option choices. |
| 71 | + - If the parent question is `select_one`, the choice filter expression will be **filter_column = ${question_name}**, where `question_name` refers to the parent question. |
| 72 | + - If the parent question is `select_multiple`, the choice filter expression will be **selected(${question_name}, filter_column).** |
| 73 | + |
| 74 | +When a respondent selects an option in the parent question, the choice list for the child question will be filtered to only include the corresponding choices. |
| 75 | + |
| 76 | +### Example |
| 77 | + |
| 78 | +In the example below, `continent` is the **parent question** and `country` is the **child question.** The choice list for the `country` question will be filtered based on the response to the `continent` question. |
| 79 | + |
| 80 | +**survey worksheet** |
| 81 | + |
| 82 | +| type | name | label | choice_filter | |
| 83 | +|:------------------|:---------|:----------|:--------------------| |
| 84 | +| select_one continent | continent | Continent | | |
| 85 | +| select_one country | country | Country | continent = ${continent} | |
| 86 | +| survey | |
| 87 | + |
| 88 | +**choices worksheet** |
| 89 | + |
| 90 | +| list_name | name | label | continent | |
| 91 | +|:-----------|:---------|:--------|:----------| |
| 92 | +| continent | africa | Africa | | |
| 93 | +| continent | asia | Asia | | |
| 94 | +| country | malawi | Malawi | africa | |
| 95 | +| country | zambia | Zambia | africa | |
| 96 | +| country | india | India | asia | |
| 97 | +| country | pakistan | Pakistan| asia | |
| 98 | +| choices | |
| 99 | + |
| 100 | +## Advanced choice filters in XLSForm |
| 101 | + |
| 102 | +You can create more advanced choice filters by using logical operators, mathematical operators, functions, and regex in your choice filter expressions. This allows for highly customized and precise filtering of options, tailoring the form to specific data collection requirements and respondent characteristics. |
| 103 | + |
| 104 | +<p class="note"> |
| 105 | +<strong>Note:</strong> In advanced choice filter expressions, the `name` column of the `choices` spreadsheet can be used as a filter column. |
| 106 | +</p> |
| 107 | + |
| 108 | +Examples of advanced choice filter expressions in XLSForm include: |
| 109 | +| Choice filter | Description | |
| 110 | +|:---------------|:------------| |
| 111 | +| `selected(${parent_question}, name)` | Display only responses that were selected in a previous `parent_question`. | |
| 112 | +| `filter = 'outdoors' and include = 'yes'` | Combine choice filter expressions so both conditions must apply for the choice to be displayed. | |
| 113 | +| `name != 'none'` | Exclude the <strong>None</strong> option from a choice list. | |
| 114 | +| `selected(${Q1}, name) or name='none'` | Include choices selected in a previous question as well as a <strong>None</strong> option (even if not selected previously). | |
| 115 | +| `filter=${Q1} or name='other'` | Include choices based on a previous question as well as an <strong>Other</strong> option. | |
| 116 | +| `filter=${Q1} or always_include='yes'` | Include choices based on a previous question as well as a set of options that should always be included. | |
| 117 | +| `filter <= ${product_count}` | Use numbers in the filter column instead of text, and filter based on a number from a previous question or calculation. | |
| 118 | +| `if(${relationship_status} = 'married', filter = 'married', filter = 'unmarried')` | Use if-statements to conditionally display choices based on the respondent’s background. | |
| 119 | + |
| 120 | +<p class="note"> |
| 121 | + To learn more about building form logic expressions in XLSForm, see <a href="https://support.kobotoolbox.org/form_logic_xls.html">Introduction to form logic in XLSForm</a>. |
| 122 | +</p> |
| 123 | + |
| 124 | +### Example |
| 125 | +In the example below, the underlying choice list for `Q1` and `Q2` is the same, but only the options selected in `Q1` will be displayed to respondents when answering `Q2`. |
| 126 | + |
| 127 | +**survey worksheet** |
| 128 | + |
| 129 | +| type | name | label | choice_filter | |
| 130 | +|:------------------|:-----|:--------------------------------------------------|:-------------------------| |
| 131 | +| select_multiple item | Q1 | Which household items do you currently own? | | |
| 132 | +| select_multiple item | Q2 | Which of these items would you consider upgrading in the future? | selected(${Q1}, name) | |
| 133 | +| survey | |
| 134 | + |
| 135 | +**choices worksheet** |
| 136 | + |
| 137 | +| list_name | name | label | |
| 138 | +|:----------|:----------|:----------------| |
| 139 | +| item | fridge | Refrigerator | |
| 140 | +| item | tv | Television | |
| 141 | +| item | fan | Ceiling fan | |
| 142 | +| item | microwave | Microwave oven | |
| 143 | +| item | radio | Radio | |
| 144 | +| item | bike | Bicycle | |
| 145 | +| item | phone | Mobile phone | |
| 146 | +| item | laptop | Laptop computer | |
| 147 | +| choices | |
| 148 | + |
| 149 | +In the resulting form, `Q2` will display only the options chosen in `Q1`, as shown below. |
| 150 | + |
| 151 | + |
| 152 | + |
| 153 | +## Troubleshooting |
| 154 | + |
| 155 | +<details> |
| 156 | + <summary><strong>Form slows or crashes with very long lists</strong></summary> |
| 157 | + Large choice lists which include thousands of rows may work in preview but fail when deployed. This happens because browser preview can handle large lists, while the mobile app or XLS parser cannot. To fix this, move large lists to an external CSV file and use <a href="https://support.kobotoolbox.org/select_from_file_xls.html">select_from_file questions</a> with choice filters. This approach is recommended for lists with more than 3,000 options. |
| 158 | +</details> |
| 159 | + |
| 160 | +<br> |
| 161 | + |
| 162 | +<details> |
| 163 | + <summary><strong>Duplicate option names in a list</strong></summary> |
| 164 | + If your choice list includes duplicate option names (for example, if the same neighborhood name is present in different cities), <a href="https://support.kobotoolbox.org/form_settings_xls.html">enable choice duplicates</a> in the `settings` worksheet by setting <code>`allow_choice_duplicates`</code> to <code>`yes`</code>. |
| 165 | +</details> |
| 166 | + |
| 167 | + |
| 168 | + |
0 commit comments