Collecting participant information
In this section, we’ll add a consent form and a section for participants to input their ID.
Obtaining participant consent
An Html element lets you insert an existing HTML document into a PennController experiment. This can be useful for displaying an informed consent form; instead of creating and printing many Text elements, you can print a single Html element.
We’ll use the mock consent form consent.html
.
consent.html
is only for illustrative purposes and is not a real consent form. You should follow your institution’s guidelines for informed consent.
The consent form has an checkbox that the participant should click to give consent. Make the checkbox an obligatory field by adding the "obligatory"
class to the HTML <input>
tag, as in <input type="checkbox" class="obligatory">
. The "obligatory"
class comes from the Ibex Form
controller.
Text areas, text boxes, and radio buttons can also be made into obligatory fields. For more information on obligatory fields, read the Html
element type documentation.
Some commands interact with obligatory fields, for example:
checkboxWarning
: Defines (but does not print) an error message for an unfilled obligatory checkbox.warn
: Prints a defined error message for every unfilled obligatory field.test.complete
: Tests whether all obligatory fields have been filled out.
The test.complete
command is a test command. Test commands have the prefix test.
, and test some aspect of the element they are called on. The success
and failure
keywords define a block of commands that are executed upon success or failure of the test, respectively:
PennController.ResetPrefix(null)
newTrial("TRIAL_LABEL",
newX("ELEMENT_1", ...)
.test.COMMAND_1()
.success(...)
.failure(...)
)
You can express the negation of a test by replacing the test.
prefix with testNot.
, and you can use the keywords and
and or
to combine tests. For more information, read the Test commands documentation.
Test commands are used in two ways:
- Within a trial to define conditional branching; or
- Within a
wait
command to modify its success condition(s).
We’ll pass the test command test.complete
as an argument to a wait
command on a Button element.
Normally, if the wait
command is called on a Button, experiment script execution pauses until the wait
command’s success condition is fulfilled, in other words until the participant clicks the button. When a test command is passed as an argument, the wait
command’s success condition is modified.
The test is run when the participant clicks the button, and experiment script execution is paused until the participant clicks the button and the test succeeds. If the participant clicks the button and the test fails, then experiment script execution remains paused. The test is run again the next time the participant clicks the button.
- Create a new trial labeled
"consent"
. - Modify the
Sequence
global command to include the"consent"
trial. - Create and print an Html named
"consent_form"
.- Call the
cssContainer
command to set the container width to 720px. - Call the
checkboxWarning
command to define an error message for an unfilled obligatory checkbox.
- Call the
- Create and print a centered Button named
"continue"
.- Call the
wait
command on the"continue"
Button and pass thetest.complete
test command on the"consent_form"
Html as an argument. This pauses experiment script execution until the participant clicks the button and all obligatory fields are filled out. - Use the
failure
keyword on thetest.complete
command. If the consent checkbox is not filled out when the participant clicks the button, PennController calls thewarn
command on the"consent_form"
Html, which prints the error message defined by thecheckboxWarning
command.
- Call the
@// code omitted in the interest of space
@
@// Control trial sequence
!Sequence("consent", "instructions", randomize("experimental-trial"), "send", "completion_screen")
@
+// Consent form
+newTrial("consent",
+ newHtml("consent_form", "consent.html")
+ .cssContainer({"width":"720px"})
+ .checkboxWarning("You must consent before continuing.")
+ .print()
+ ,
+ newButton("continue", "Click to continue")
+ .center()
+ .print()
+ .wait(getHtml("consent_form").test.complete()
+ .failure(getHtml("consent_form").warn())
+ )
+)
@
@// Instructions
@// code omitted in the interest of space
Recording participant IDs
A TextInput element creates a text input box that can collect participant input, like an ID number or experiment feedback.
We’ll ask participants to enter a name or ID number before they start the experiment, and use the log
method to record the content of the TextInput as a new column in the results
file.
However, you cannot directly pass the content of a TextInput as an argument to the log
method. Create a Var element, make it a global variable, and set its value to the content of the TextInput. A global variable can be accessed in subsequent trial objects; a non-global variable can only be accessed in the trial that it’s created in. Then, you can pass the Var as an argument to the log
method.
- Update the instructions.
- Create and print a TextInput named
"input_ID"
that is centered and has a 1em bottom margin. - Create a Var named
"ID"
. - Use the
log
method on the"experimental-item"
trial to record the participant ID.
@// code omitted in interest of space
@
@// Instructions
@newTrial("instructions",
@ defaultText
+ .cssContainer({"margin-bottom":"1em"})
@ .center()
@ .print()
@ ,
@ newText("instructions-1", "Welcome!")
@ ,
@ newText("instructions-2", "In this experiment, you will hear and read a sentence, and see two images.")
@ ,
@ newText("instructions-3", "<b>Select the image that better matches the sentence:</b>")
@ ,
@ newText("instructions-4", "Press the <b>F</b> key to select the image on the left.<br>Press the <b>J</b> key to select the image on the right.<br>You can also click on an image to select it.")
@ ,
@ newText("instructions-5", "If you do not select an image by the time the audio finishes playing,<br>the experiment will skip to the next sentence.")
+ ,
+ newText("instructions-6", "Please enter your ID and then click the button below to start the experiment.")
+ ,
+ newTextInput("input_ID")
+ .cssContainer({"margin-bottom":"1em"})
+ .center()
+ .print()
@ ,
@ newButton("wait", "Click to start the experiment")
@ .center()
@ .print()
@ .wait()
+ ,
+ newVar("ID")
+ .global()
+ .set(getTextInput("input_ID"))
@)
@
@// Experimental trial
*Template("items.csv", row =>
@ newTrial("experimental-trial",
@ // code omitted in interest of space
@ )
@ .log("group", row.group)
@ .log("item", row.item)
@ .log("condition", row.inflection)
+ .log("ID", getVar("ID"))
@)
@
@// code omitted in interest of space