DropDown element

DropDown elements let you add drop-down lists of options onto the page.

Creation:

newDropDown("name", "default text")

Example:

newDropDown("warmth", "Select an adjective")
    .settings.add( "hot" , "lukewarm" , "cold" ) 
    .print()

The code above adds a drop-down list containing hot, lukewarm and cold onto the page.

Actions

dropdown.select

getDropDown(id).select( "option" )

Selects an option in the drop-down list. Nothing happens if the option passed as an argument does not exist.

Example:

newDropDown("warmth", "")
    .settings.add("hot", "lukewarm", "cold")
    .select( "lukewarm" )
,
newText("Spring in Colorado is  ")
    .settings.after( getDropDown("warmth") )
    .print()

Creates a drop-down list containing the options hot, lukewarm and cold, selects the option lukewarm and adds the list to the right of the text Spring in Colorado is, then prints everything onto the page.

dropdown.shuffle

getDropDown(id).shuffle()

or getDropDown(id).shuffle( "keep selected" )

Shuffles the options that have been added to the DropDown so far. If you call shuffle before settings.add then it will have no effect.

Passing an argument means that you want any option currently selected to remain selected after the shuffle ("keep selected" is simply given as an example—you can pass an arbitrary string).

Example:

newDropDown("warmth", "")
    .settings.add("hot", "lukewarm", "cold")
    .shuffle()
,
newText("Spring in Colorado is  ")
    .settings.after( getDropDown("warmth") )
    .print()
,
getDropDown("warmth")
    .wait()

Creates a drop-down list containing the options hot, lukewarm and cold, shuffles them, adds the drop-down list to the right of the text Spring in Colorado is and prints everything onto the page, then waits until an option is selected from the drop-down list before proceeding.

dropdown.wait

getDropDown(id).wait()

or getDropDown(id).wait("first")

or getDropDown(id).wait(test)

Waits until an option is selected from the drop-down list before proceeding.

If you call wait("first"), then if an option has already been selected by the time this command is evaluated, the next commands are evaluated and executed right away. If no option has been selected so far, the next commands are only evaluated and executed after a selection happens.

If you pass a test on an element as an argument, it only evaluates and executes the next commands when a selection happens while the test is successful. If the test is not successful, it will be checked again next time a selection happens.

Example:

newText("I want ")
    .settings.after( newDropDown("what", "").settings.add("candy","to break free") )
    .print()
,
newTimer("read", 2000)
    .start()
    .wait()
,
getDropDown("what")
    .wait("first")

Prints the text I want and, to its right, a drop-down list containing candy and to break free onto the page, then waits 2s and waits until an option is selected before proceeding. Since wait was called with the argument "first", execution will immediately proceed at the end of the 2s timer if an option was selected in the meantime, or it will wait for a selection to happen is no option has been selected at the end of the 2s timer.

standard.print

getElement(id).print()

or getElement(id).print(x,y) (limited support in PennController 1.3, general since 1.4)

or getElement(id).print(x,y,canvas) (limited support in PennController 1.3, general since 1.4)

Adds the content of the element to the screen. This has no effect for non-visual elements such as the purely interactive Selector elements.

Since PennController 1.3, you can pass x and y values to print the element at a specific position on the page, or on a Canvas element if you pass one (or the name of a Canvas element) as the third parameter. You can use any CSS coordinate format for x and y, or special string values following the respective formats "left|center|right at ..." and "top|middle|bottom at ...". Note that x and y are not supported for Audio, Canvas, Scale, TextInput, Video and Youtube elements in PennController 1.3 ; note also that elements added with .settings.before and .settings.after mess with proportional coordinates.

standard.refresh

getElement(id).refresh() (since PennController 1.1)

Calls the command print again on the element, while leaving it where it was printed last.

This command is primarily useful if some aesthetic command does not take effect unless print is called afterward, but you do not want to call print because calling it when you need the aesthetic command to take effect would move the element undesirably.

NOTE: PennController 1.1 handles this command incorrectly and it bugs systematically (draft)

Example:

newImage( "smiley" , "ya.png" )
,
newCanvas( "myCanvas" , 100 , 100 )
    .settings.css( "border" , "solid 1px black" )
    .settings.center()
    .settings.add( "center at 50%" , "center at 50%" , getImage("smiley") )
    .print()
,
newButton( "resize" , "Resize the image" )
    .print()
    .wait()
,
getImage( "smiley" )
    .settings.size( 64, 64 )
,
getCanvas("myCanvas")
    .refresh()

Prints the smiley image at the center of the canvas and adds a button below the canvas. After the button is clicked, the smiley is resized to 64×64 and without refresh the smiley would no longer be centrally aligned on canvas. Calling print on the canvas would recenter the image correctly, but it would move the canvas below the button. The solution is therefore to call refresh (or to call the settings command add again on the canvas).

standard.remove

getElement(id).remove()

Removes the element from the screen. This has no effect for non-visual elements such as the purely interactive Selector elements.

Note that this leaves no space where the element previously was on the page (this is really removing the element, not just hiding it).

Example

newButton("clickme", "Click me")
    .print()
    .wait()
    .remove()

Adds a button that says Click me to the screen, and removes it after it is clicked.

standard.setVar

getElement(id).setVar( varName ) (since beta 0.3)

Stores the current value of the element in the Var element named varName (if it exists).

What the current value corresponds to is specific to each element type:

  • For Audio elements, it corresponds to the timestamp of the end of the last playback so far (0 if never played back or playback never eneded).
  • For Button elements, it corresponds to the timestamp of the last click so far (0 if never clicked).
  • For Canvas elements, it corresponds to the number of elements it currently contains.
  • For Function elements, it corresponds to the value returned by the function.
  • For Html elements, it corresponds to whether the element is completely filled.
  • For Image elements, it corresponds to whether the image is currently being displayed.
  • For Key elements, it corresponds to the last key that was pressed so far (empty string if no key has been pressed so far).
  • For Scale elements, it corresponds to the value of the last option that was selected (NaN if no option has been selected so far).
  • For Selector elements, it corresponds to the last element that was selected (null if no element has been selected so far).
  • For Text elements, it corresponds to the current text.
  • For TextInput elements, it corresponds to the text that is currently in the input box.
  • For Timer elements, it corresponds to whether the timer has elapsed.
  • For Tooltip elements, it corresponds to whether the tooltip has been validated.
  • For Var elements, it corresponds to the element’s value.
  • For Video elements, it corresponds to the timestamp of the end of the last playback so far (0 if never played back or playback never eneded).
  • For VoiceRecorder elements, it corresponds to the last recording (undefined if no recording so far).
  • For Youtube elements, it corresponds to whether the video has been played.

Example:

newVar("name")
,
newTextInput("nameInput", "What is your name?")
    .settings.once()
    .print()
    .wait()
    .setVar("name")
,
newText("helloname")
    .settings.before( newText("hello", "Hello ") )
    .settings.text( getVar("name") )
    .print()

Creates a Var element named name and adds a text box in which to enter a name. When the return/enter key is pressed while editing the input box, it disables the box and stores its value in the Var element named name. Then it prints a text reading Hello name, where name corresponds to the value of the Var element.

Settings

dropdown.settings.add

getDropDown(id).settings.add("option")

or getDropDown(id).settings.add("option1","option2",...)

Adds an option, or several options to the drop-down list.

Example:

newDropDown("language" , "First language")
    .settings.add( "English" , "French" , "Tagalog" )
    .print()

Creates a drop-down list with default text First language and adds three options to it: English, French and Tagalog, then prints the list onto the page.

dropdown.settings.callback

getDropDown(id).settings.callback( command ) (since PennController 1.5)

or getDropDown(id).settings.callback( command1, command2 ) (since PennController 1.5)

Will execute the command(s) whenever an option is selected from the drop-down list.

Example:

newText("The weather is")
    .settings.after( newDropDown("temp","...").settings.add("cold","warm","hot") )
    .settings.after( newText("implicature", "implies that the weather is ...") )
    .print()
,
getDropDown("temp")
    .settings.callback(
        getDropDown("temp")
            .test.selected("warm").success( 
                getText("implicature").settings.text("implicates that the weather is not hot") 
            )
            .test.selected("hot").success( 
                getText("implicature").settings.text("implies that the weather is not cold") 
            )
            .test.selected("cold").success( 
                getText("implicature").settings.text("implies that the weather is not even warm") 
            )
    )

Prints The weather is … implies that the weather is … onto the page, where the first occurrence of is a drop-down list containing the options cold, warm and hot. Upon selection of the option, the continuation will be modified accordingly to the selected option.

dropdown.settings.log

getDropDown(id).settings.log()

or getDropDown(id).settings.log("first")

or getDropDown(id).settings.log("all")

Will add a line to the results file for the current trial reporting what option was selected.

If you pass “first” as the argument, it will report the option selected upon first selection, ignoring further selections. If you pass “all” as the argument, it will add a line for each single occurrence of a selection. By default (no argument) it will only add a line for the value selected at the end of the trial.

dropdown.settings.once

getDropDown(id).settings.once() (since PennController 1.5)

Will disable the DropDown element after selection occurs.

Example:

newText("I saw Erika talk to Nate.")
    .settings.after( newDropDown("").settings.add("He","She").settings.once() )
    .settings.after( newText("seemed anxious.") )
    .print()

Prints I saw Erika talk to Nate. ___ seemed nervous onto the page, where ___ is a drop-down list containing the options He and She. The command .settings.once makes the selection of He or She definitive.

dropdown.settings.remove

getDropDown(id).settings.remove("option")

Removes a single option from the list. Nothing happens if the option passed as an argument is in fact not in the list.

Example:

newDropDown("value" , "Truth value")
    .settings.add( "True" , "False" )
    .print()
,
newScale("logic",  "Binary","Three-valued")
    .settings.default("Binary")
    .settings.before( newText("Logic: ") )
    .settings.labelsPosition("right")
    .settings.callback(
        getScale("logic")
            .test.selected("Three-valued")
            .success( 
                getDropDown("value")
                    .settings.add("Other") 
            )
            .failure( 
                getDropDown("value")
                    .settings.remove("Other") 
            )
    )
    .print()

Creates a drop-down list with two options, True and False, and prints it onto the page. Then creates a Scale element with two options, Binary and Three-value, the former being selected by default, preceded with the text Logic:. Whenever a value gets selected on the Scale, a test checks whether the selected value corresponds to Three-valued and, if so, it adds the option Other to the drop-down list, or removes it from the list otherwise.

standard.settings.selector

getElement(id).settings.selector( selectorName )

or getElement(id).settings.selector( getSelector(selectorName) ) (since beta 0.3)

Since beta 0.3, Selector adds a .settings.selector command to all elements as another method for adding them to a selector.

Example:

newSelector("shapes")
,
newImage("square", "square.png")
    .settings.selector("shapes")
,
newImage("triangle", "triangle.png")
    .settings.selector("shapes")
,
newCanvas("shapes canvas", 825, 400)
    .settings.add(  0, 0, getImage("square") )
    .settings.add(425, 0, getImage("triangle") )
    .print()
,
getSelector("shapes")
    .wait()

Adds two images side by side and waits for a click on either one of them.

standard.settings.after

getElement(id).settings.after( getElement(id) )

Adds some content to the right of the element.

Example:

newImage("bad", "no.png")
,
newImage("good", "ya.png")
,
newText("left label", "Bad")
    .settings.before( getImage("bad") )
,
newText("right label", "Good")
    .settings.after( getImage("good") )
,
newScale("judgment", 5)
    .settings.before( getText("left label") )
    .settings.after( getText("right label") )
    .print()
    .wait()

Creates two image and two text elements and prints a 5-point radio-button scale, with the text Bad preceded by the image no.png on its left, and the text Good followed by the image ya.png on its right.

standard.settings.before

or getElement(id).settings.before( getElement(id) )

Adds some content to the left of the element.

Example:

newImage("bad", "no.png")
,
newImage("good", "ya.png")
,
newText("left label", "Bad")
    .settings.before( getImage("bad") )
,
newText("right label", "Good")
    .settings.after( getImage("good") )
,
newScale("judgment", 5)
    .settings.before( getText("left label") )
    .settings.after( getText("right label") )
    .print()
    .wait()

Creates two image and two text elements and prints a 5-point radio-button scale, with the text Bad preceded by the image no.png on its left, and the text Good followed by the image ya.png on its right.

standard.settings.bold

getElement(id).settings.bold()

Makes any text in the element appear boldfaced.

Example:

newText("warnning", "NOTE: this text is a warning!")
    .settings.bold()
    .settings.italic()
    .settings.color("red")
    .print()

Prints a text in boldface, italic and red.

standard.settings.center

getElement(id).settings.center()

Makes the element appear centered on the horizontal axis.

Example:

newText("helloworld", "Hello world")
    .settings.center()
    .print()

Prints Hello world onto the screen, horizontally centered.

standard.settings.color

getElement(id).settings.color("color")

Makes any text in the element appear in the specified color. The "color" string follows CSS conventions (most common names such as “red”, “blue”, … are valid)

Note: if you want to change the background color of an element (say, a Canvas element) use .settings.css("background", color) where color is the name of a color (e.g. "green")

Example:

newText("warnning", "NOTE: this text is a warning!")
    .settings.bold()
    .settings.italic()
    .settings.color("red")
    .print()

Prints a text in boldface, italic and red.

standard.settings.css

getElement(id).settings.css("styleName", "style")

or getElement(id).settings.css({"style name 1": "style 1", "style name 2": "style 2"})

Applies the CSS style(s) to the element.

Example:

newText("frame", "framed")
    .settings.css("border", "solid 1px black")
,
newText("sentence", "The last word of this sentence is ")
    .settings.after( getText("frame") )
    .print()

Prints a text reading The last word of this sentence is framed, with the last word (framed) framed in a box with 1px black borders.

standard.settings.disable

getElement(id).settings.disable()

Disables any interactive feature of the element.

Note: this does not prevent an element that is part of a Selector element from being selected.

Example:

newAudio("sentence", "test.mp3")
    .print()
    .wait()
,
getAudio("sentence")
    .settings.disable()

Prints buttons to play/pause the audio file test_sentence.ogg, and disables those buttons when the file has played through.

standard.settings.enable

getElement(id).settings.enable()

Enables any interactive feature of the element that was previously disabled.

Example:

newAudio("sentence", "test.mp3")
    .settings.once()
    .print()
,
newKey("secret key", "R")
    .wait()
,
getAudio("sentence")
    .settings.enable()

Prints buttons to play/pause the audio file test_sentence.ogg, and disables those buttons when the file has played through (see audio.settings.once).

standard.settings.hidden

getElement(id).settings.hidden() (since beta 0.3)

Makes the element invisible. Note that when printed, a hidden element still occupies space on the page, but its content is not visible.

Example:

newText("instruction", "Guess what fruit is in the image below")
    .print()
,
newImage("fruit", "pear.png")
    .settings.hidden()
    .print()
,
newButton("reveal", "Reveal fruit")
    .print()
    .wait()
,
getImage("fruit")
    .settings.visible()

Adds some text to the page, a blank space below it and a button below the blank space which, when clicked, reveals an image of a pear.

standard.settings.italic

getElement(id).settings.italic()

Makes any text in the element appear in italic.

Example:

newText("warnning", "NOTE: this text is a warning!")
    .settings.bold()
    .settings.italic()
    .settings.color("red")
    .print()

Prints a text in boldface, italic and red.

standard.settings.left

getElement(id).settings.left()

Makes the element appear horizontally aligned to the left (default).

Note: the left means the left of the container of the element, not necessarily the left of the screen.

Example:

newText("helloworld", "Hello world")
    .settings.right()
    .print()
,
newButton("left", "Align text to the left")
    .print()
    .wait()
,
getText("helloworld")
    .settings.left()

Prints Hello world onto the screen, horizontally aligned to the left.

standard.settings.right

getElement(id).settings.right()

Makes the element appear horizontally aligned to the right.

Note: the right means the right of the container of the element, not necessarily the right of the screen.

Example:

newText("sentence", "This is a longer sentence")
    .print()
,
newText("helloworld", "Hello world")
    .settings.right()
    .print()

Prints Hello world onto the screen, horizontally aligned to the right.

standard.settings.size

getElement(id).settings.size(width, height)

Resizes the element to a width of width pixels and a height of height pixels.

Example:

newImage("smiley", "pear.png")
    .settings.size(40, 40)
    .print()

Adds a 40x40px image pear.png onto the screen.

standard.settings.visible

getElement(id).settings.visible() (since beta 0.3)

Makes the element visible (again). This is useful if you previously hid the element with .settings.hidden.

Example:

newText("instruction", "Guess what fruit is in the image below")
    .print()
,
newImage("fruit", "pear.png")
    .settings.hidden()
    .print()
,
newButton("reveal", "Reveal fruit")
    .print()
    .wait()
,
getImage("fruit")
    .settings.visible()

Adds some text to the page, a blank space below it and a button below the blank space which, when clicked, reveals an image of a pear.

Tests

dropdown.test.selected

getDropDown(id).test.selected(option)

or getDropDown(id).test.selected()

Tests whether an option is selected. If you pass no option as an argument, then the test will succeed as long as any option is selected.

If you pass a number, and provided there is no option whose text content corresponds to this exact number, it will test the index of the selected option (starting from 0).

Example:

newDropDown("adjective", "")
    .settings.add( "hot"  , "lukewarm" , "cold" )
    .shuffle()
    .print()
    .wait()
,
getDropDown("adjective")
    .test.selected( 1 )
    .success(
        newText("You selected the middle option (index-based).")
            .print()
    )
    .failure(
        getDropDown("adjective")
            .test.selected( "lukewarm" )
            .success(
                newText("You selected the middle option (scale-based)")
                    .print()
            )
    )

Creates a drop-down list with three options, hot, lukewarm and cold, shuffles the options, prints the list and waits until an option is selected before proceeding. After an option is selected, tests whether the option at index 1 was selected and, if so, will print You selected the middle option (index-based), otherwise will test whether the option lukewarm was selected and, if so, will print You selected the middle option (scale-based).

standard.test.printed

getElement(id).test.printed() (since beta 0.3)

Tests whether the element was printed onto the page (and has not been removed since then).

Example:

newText("instructions", "Click on Top/Bottom to NOT print its word")
    .print()
,
newButton("top", "Top")
    .settings.callback( getButton("top").remove() ) 
    .print()
,
newButton("bottom", "Bottom")
    .settings.callback( getButton("bottom").remove() )
    .print()
,
newButton("print", "Print the buttons' words")
    .print()
    .wait()
    .remove()
,
getButton("top")
    .test.printed()
    .success( newText("top word", "hello").print() )
,
getButton("bottom")
    .test.printed()
    .success( newText("bottom word", "world").print() )

Prints a Top and a Bottom button onto the page, which disappear when clicked. After a click on the print button, the word hello will appear if the top button is still displayed, and the word world will appear if the bottom button is still displayed.