Skip to content

Commit a2bbc81

Browse files
Merge pull request #249 from kobotoolbox/248-support-dymanic-select-one-choice-list
Support choice from previous repeat answers for `select_one`
2 parents 34d40a7 + cf673f0 commit a2bbc81

File tree

4 files changed

+162
-2
lines changed

4 files changed

+162
-2
lines changed

src/formpack/schema/fields.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,14 +150,22 @@ def from_json_definition(cls, definition, hierarchy=None,
150150

151151
# normalize spaces
152152
data_type = definition['type']
153-
choice = None
154153

155154
if ' ' in data_type:
156155
raise ValueError('invalid data_type: %s' % data_type)
157156

158157
if data_type in ('select_one', 'select_multiple'):
159158
choice_id = definition['select_from_list_name']
160-
choice = field_choices[choice_id]
159+
# pyxform#472 introduced dynamic list_names for select_one with the
160+
# format of `select_one ${question_name}`. The choices are
161+
# therefore not within a separate choice list
162+
if choice_id.startswith('${') and choice_id.endswith('}'):
163+
# ${dynamic_choice}, so question will be treated as a TextField
164+
choice = None
165+
else:
166+
choice = field_choices[choice_id]
167+
else:
168+
choice = None
161169

162170
data_type_classes = {
163171
# selects
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# coding: utf-8
2+
3+
from __future__ import (unicode_literals, print_function,
4+
absolute_import, division)
5+
6+
'''
7+
select_one_from_previous_answers
8+
9+
'''
10+
11+
from ..load_fixture_json import load_fixture_json
12+
13+
DATA = {
14+
'title': 'Household survey with select_one from previous answers',
15+
'id_string': 'select_one_from_previous_answers',
16+
'versions': [
17+
load_fixture_json('select_one_from_previous_answers/v1'),
18+
],
19+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"version": "romev1",
3+
"content": {
4+
"survey": [
5+
{
6+
"name": "Q1",
7+
"type": "integer",
8+
"label": [
9+
"How many members live in your family?"
10+
]
11+
},
12+
{
13+
"name": "FM",
14+
"type": "begin_repeat",
15+
"label": [
16+
"Family Members"
17+
],
18+
"repeat_count": "${Q1}"
19+
},
20+
{
21+
"name": "Q2",
22+
"type": "text",
23+
"label": [
24+
"Name?"
25+
]
26+
},
27+
{
28+
"name": "Q3",
29+
"type": "integer",
30+
"label": [
31+
"${Q2}'s age?"
32+
]
33+
},
34+
{
35+
"type": "end_repeat"
36+
},
37+
{
38+
"name": "Q4",
39+
"type": "select_one",
40+
"label": [
41+
"Select the head of the household."
42+
],
43+
"select_from_list_name": "${Q2}"
44+
},
45+
{
46+
"name": "Q5",
47+
"type": "select_one",
48+
"label": [
49+
"Select the youngest child (<18 years) who is currently available in the family."
50+
],
51+
"choice_filter": "${Q3} < 18",
52+
"select_from_list_name": "${Q2}"
53+
}
54+
]
55+
},
56+
"submissions": [
57+
{
58+
"FM": [
59+
{
60+
"FM/Q2": "Julius Caesar",
61+
"FM/Q3": "53"
62+
},
63+
{
64+
"FM/Q2": "Gaius Octavius",
65+
"FM/Q3": "17"
66+
}
67+
],
68+
"FM_count": "2",
69+
"Q1": "2",
70+
"Q4": "Julius Caesar",
71+
"Q5": "Gaius Octavius",
72+
"meta/versionID": "romev1",
73+
"meta/instanceID": "uuid:40805f86-2638-46f1-ab5a-72f4632474b5"
74+
}
75+
]
76+
}

tests/test_exports.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,63 @@ def test_repeats(self):
415415
])
416416
)
417417

418+
def test_select_one_from_previous_answers(self):
419+
title, schemas, submissions = build_fixture(
420+
'select_one_from_previous_answers'
421+
)
422+
fp = FormPack(schemas, title)
423+
options = {'versions': 'romev1'}
424+
export = fp.export(**options).to_dict(submissions)
425+
expected_dict = OrderedDict(
426+
[
427+
(
428+
'Household survey with select_one from previous answers',
429+
{
430+
'fields': [
431+
'Q1',
432+
'Q4',
433+
'Q5',
434+
'_index',
435+
],
436+
'data': [
437+
[
438+
'2',
439+
'Julius Caesar',
440+
'Gaius Octavius',
441+
1,
442+
]
443+
],
444+
},
445+
),
446+
(
447+
'FM',
448+
{
449+
'fields': [
450+
'Q2',
451+
'Q3',
452+
'_parent_table_name',
453+
'_parent_index',
454+
],
455+
'data': [
456+
[
457+
'Julius Caesar',
458+
'53',
459+
'Household survey with select_one from previous answers',
460+
1,
461+
],
462+
[
463+
'Gaius Octavius',
464+
'17',
465+
'Household survey with select_one from previous answers',
466+
1,
467+
],
468+
],
469+
},
470+
),
471+
]
472+
)
473+
self.assertEqual(export, expected_dict)
474+
418475
def test_nested_repeats_with_copy_fields(self):
419476
title, schemas, submissions = build_fixture(
420477
'nested_grouped_repeatable')

0 commit comments

Comments
 (0)