-
Notifications
You must be signed in to change notification settings - Fork 0
faq004_dynamic page display
There are two major ways to do this:
- Use a filter function and a simple switch at the end of Section 4
- Define a custom class with a switch in the method
onHidingWidget()
Feel free to use the option that seems more straightforward to you.
Download minimal example: script.py
In Section 2 of your script.py
, you can define filter functions that return True
or False
. These functions allow you to toggle the display of question groups at the end of Section 4 using the command questionGroup.setShouldBeShownFilterFunction(function)
, where questionGroup
is a placeholder for the name of your question group and function
is a placeholder for the name of your function.
In the example below, the display of Page 2 is toggled depending on the answer to the question p1_mc
on Page 1. We define two filter functions: One that returns True
of the answer is "1" and False
otherwise, and one that returns True
when the answer is "2" and False
otherwise.
This is what your Section 2 would look like:
#################################################
### Section 2: Global variables and functions ###
#################################################
expName='Alfred Beispiel'
expVersion='0.01'
def filter_condition1(experiment):
cond_condition=experiment.dataManager.findExperimentDataByUid('page1')['p1_mc']
if cond_condition == 1:
return True
else:
return False
def filter_condition2(experiment):
cond_condition=experiment.dataManager.findExperimentDataByUid('page1')['p1_mc']
if cond_condition == 2:
return True
else:
return False
Section 3 is empty in this example, as we don't need to define a new custom class. This is what Section 4 would look like in this example:
########################################
### Section 4: Experiment generation ###
########################################
class Script(object):
def generate_experiment(self):
exp=Experiment('web', expName, expVersion)
# Define Page 1
p1=CompositeQuestion(title=u"Hello World", uid=u"page1")
p1_text=TextElement("This is a minimal example.")
p1_mc=SingleChoiceElement(u"Pick one option.",
itemLabels=["Option 1", "Option 2"],
name="p1_mc",
forceInput=True)
p1.addElements(p1_text, p1_mc)
# Define Question Group for Page 1
startQG=SegmentedQG()
startQG.appendItems(p1)
# Define Page 2
p2=CompositeQuestion(title=u"Page 2")
p2_text=TextElement("You chose option 1.")
p2.addElements(p2_text)
# Define Page 3
p3=CompositeQuestion(title=u"Page 3")
p3_text=TextElement(
"This is page 3. If you see this right after the Hello World page, you chose option 2. Page 2 is not displayed in this condition.")
p3.addElements(p3_text)
# Define Two Question Groups, one containing both Pages 2 and 3, one containing only Page 3.
mainQGa=SegmentedQG()
mainQGa.appendItems(p2, p3)
mainQGb=SegmentedQG()
mainQGb.appendItems(p3)
# Use filter functions
mainQGa.setShouldBeShownFilterFunction(filter_condition1) # If filter_condition1 is True, mainQGa will be shown
mainQGb.setShouldBeShownFilterFunction(filter_condition2) # If filter_condition2 is True, mainQGb will be shown
# --- EXPERIMENT CONTROLS --- #
# ------------------------------------------------------------------- #
# All Question Groups are added here
exp.questionController.appendItems(startQG, mainQGa, mainQGb)
return exp
generate_experiment=Script().generate_experiment
Download minimal example: script.py
You can define a custom class in Section 3 that works as a switch. The trick is to define the method onHidingWidget
, which contains code that gets run when the page is closed. Depending on previous answers, you can use this method to append customized compositions of the rest of the experiment. This flowchart illustrates the process:
This is what the Sections 3 and 4 of your scipt.py
would look like when you use this solution.
#################################
### Section 3: Custom classes ###
#################################
class StartQuestion(CompositeQuestion):
# Define dynamic actions on closing of the page
def onHidingWidget(self):
mainQG=SegmentedQG() # Define an empty segmented question group
# Extract data from Page 1, Element p1_mc
# Note that Page 1 is defined below in Section 4 using the StartQuestion class defined here
condition=self._experiment.dataManager.findExperimentDataByUid('page1')['p1_mc']
# Define Page 2
p2=CompositeQuestion(title=u"Page 2")
p2_text=TextElement("You chose option 1.")
p2.addElements(p2_text)
# Define Page 3
p3=CompositeQuestion(title=u"Page 3")
p3_text=TextElement("This is page 3. If you see this right after the Hello World page, you chose option 2. Page 2 is not displayed in this condition.")
p3.addElements(p3_text)
# If condition is "1", append both Page 2 and 3 to the mainQG question group
if condition == 1:
mainQG.appendItems(p2, p3)
# If condition is "2", append only Page 3 to the mainQG question group
if condition == 2:
mainQG.appendItems(p3)
# Add the mainQG question group to the running experiment
self._experiment.questionController.appendItems(mainQG)
########################################
### Section 4: Experiment generation ###
########################################
class Script(object):
def generate_experiment(self):
exp=Experiment('web', expName, expVersion)
# --- PAGE 1 --- #
# Use the StartQuestion class defined above in Section 3 to create a page
p1=StartQuestion(title=u"Hello World", uid="page1")
# Define and add elements to the page as usual
p1_text=TextElement("This is a minimal example.")
p1_mc=SingleChoiceElement(u"Pick one option.",
itemLabels=["Option 1", "Option 2"],
name="p1_mc",
forceInput=True) # forceInput needs to be true for Alfred to correctly display
# the "continue" button at the end of the page instead of
# "end".
p1.addElements(p1_text, p1_mc)
# Define a question group and add Page 1 to it
start=SegmentedQG()
start.appendItems(p1)
# --- EXPERIMENT CONTROLS --- #
# ------------------------------------------------------------------- #
exp.questionController.appendItems(start)
return exp
generate_experiment=Script().generate_experiment
If you have trouble getting your code to work, you can contact our support via [email protected]. Please make sure to test your code diligently before asking for help.