test.selected() for multiple options

PennController for IBEX Forums Support test.selected() for multiple options

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #6162
    daniela
    Participant

    Hi,

    I’m collecting some basic demographic information to screen participants. We’ve got three drop-downs: (1) age (with 14 options we would accept, and 2 we would reject), (2) gender (not used for rejection), and (3) L2 experience (we’d only accept the option ‘none’).

    We’ve previously used test.selected() to not allow the participants to continue unless they’ve made a selection for each, but I’d now like to use test.selected() to end the experiment and present a message after the demographics page if they don’t meet the requirements set through the recruitment company (since in the last experiment several participants didn’t match our requirements).

    Here’s what I’ve tried out based on responses to similar questions on the forum:

    // ENTER DEMOGRAPHICS
                   newText("demo", "<p>Before you continue to the instructions, we need to know a few things about you."
                           +" This information will remain anonymous. You can read more about how we handle your data in our Information Sheet below.<p>")              
                   .settings.css("font-size", "20px")
                   ,
                   newCanvas("democanvas", 1000, 125)
                   .settings.add(0, 0, getText("demo") )
                   .print()
                   ,
                   newDropDown("age", "")
                   .settings.add( "17 or younger" , "18" , "19" , "20", "21" , "22" , "23", "24" , "25" , "26", "27" , "28" , "29", "30" , "31" , "32 or older" )
                   ,
                   newText("agetext", "Age:")
                   .settings.css("font-size", "20px")
                   .settings.bold()
                   //.settings.after( getDropDown("age") )    
                   ,
                   newCanvas("agecanvas", 1000, 45)
                   .settings.add(0, 10, getText("agetext") )
                   .settings.add(100, 8, getDropDown("age") )
                   .print()    
                   ,
                   newText("sex", "Gender:")
                   .settings.css("font-size", "20px")
                   .settings.bold()
                   ,
                   newDropDown("sex", "" )
                   .settings.add( "female", "male", "other")
                   ,
                   newCanvas("sexcanvas", 1000, 40)
                   .settings.add(0, 0, getText("sex") )
                   .settings.add(120, 3, getDropDown("sex") )
                   .print()
                   ,
                   newText("nativeEng", "Did you learn/speak any language other than English before the age of 6?")
                   .settings.css("font-size", "20px")
                   .settings.bold()
                   ,
                   newTextInput("L2", "")
                   .settings.hidden()
                   ,
                   newText("label input", "")
                   .settings.after( getTextInput("L2") )
                   ,
                   newDropDown("language", "")
                   .settings.log()
                   .settings.add(  "no", "yes, I learned/spoke:")    
                   .settings.after(  getText("label input") )
                   .settings.callback(                                             //whenever an option is selected, do this:
                       getDropDown("language")
                       .test.selected("yes, I learned/spoke:")                             //reveal the input box
                       .success( getTextInput("L2").settings.visible() )     //hide the input box
                       .failure( getTextInput("L2").settings.hidden()  )   
                   )        
                   ,
                   newCanvas("languagecanvas", 1000, 25)
                   .settings.add(0, 0, getText("nativeEng") )
                   .settings.add(690, 2, getDropDown("language") )
                   .print()

    // Check responses before continuing (includes reference to some canvases that I've omitted for clarity/space)
    newButton("consent", "Continue")
                   .settings.center()
                   .print()
                   .wait(getDropDown("age")
                         .test.selected( "18" , "19" , "20", "21" , "22" , "23", "24" , "25" , "26", "27" , "28" , "29", "30" , "31" ) // only works for "18"
                         .success()
                         .failure(
                             getCanvas("democanvas")
                             .remove()
                             ,
                             getCanvas("agecanvas")
                             .remove()
                             ,
                             getCanvas("sexcanvas")
                             .remove()
                             ,
                             getCanvas("languagecanvas")
                             .remove()
                             ,
                             getCanvas("infocanvastwo")
                             .remove()
                             ,
                             getCanvas("infocanvasthree")
                             .remove()
                             ,
                             getText("consent")
                             .remove()
                             ,
                             getButton("consent")
                             .remove()
                             ,
                             newText("bye", "You are ineligible for this study, as you have provided information which is inconsistent with your Prolific prescreening responses. "
                                     + "<p>Please return your submission on Prolific by selecting the 'Stop without completing' button."
                                    ) .print() 
                         )
                        )

    Firstly, I can’t figure out how to include all 14 ages we’d like to accept (perhaps it’s easier to use the 2 options we wouldn’t accept, and use success() as a path to end the experiment? We’d like to log their precise age, so simply having an option ’18-31′ isn’t feasible), and then where I would include further conditions for ‘L2’ experience (my guess is in failure() of the first test.selector()`?).

    I hope that’s all clear!

    #6163
    Jeremy
    Keymaster

    Hi,

    As you can see in the documentation the test.selected command only accepts single arguments, so yo cannot simply pass it a series of arguments in order to express a disjunctive test.

    What you can do however is use the or and and commands (which I don’t think are documented at the moment). As you said, excluding the two invalid options is more economical, so let’s do that:

    .wait( getDropDown("age")
      .testNot.selected("17 or younger")
      .and( getDropDown("age").testNot.selected("32 or older") )

    If you want to add the requirement that they not speak another language, simply stack .and( getDropDown("language").selected("no") )

    Let me know if you have questions

    Jeremy

    #6164
    daniela
    Participant

    Hi Jeremy,

    worked like a charm, thanks!

    For anybody who finds this post and wants to see how I implemented Jeremy’s response, here’s my code:

    newButton("consent", "Continue")
                   .settings.center()
                   .print()
                   .wait(getDropDown("age")
                         .testNot.selected("17 or younger")
                         .and( getDropDown("age")
                               .testNot.selected("32 or older") 
                             )
                         .and(getDropDown("language") 
                              .test.selected("no")
                              )
                         .success() // if '17 or younger' or '32 or older' are NOT selected, and 'no' IS selected, continue as normal
                         .failure(  // otherwise, remove all canvases and display the "bye" text
                             getCanvas("democanvas")
                             .remove()
                             ,
                             getCanvas("agecanvas")
                             .remove()
                             ,
                             getCanvas("sexcanvas")
                             .remove()
                             ,
                             getCanvas("languagecanvas")
                             .remove()
                             ,
                             getCanvas("infocanvastwo")
                             .remove()
                             ,
                             getCanvas("infocanvasthree")
                             .remove()
                             ,
                             getText("consent")
                             .remove()
                             ,
                             getButton("consent")
                             .remove()
                             ,
                             newText("bye", "You are ineligible for this study, as you have provided information which is inconsistent with your Prolific prescreening responses. "
                                     + "<p>Please return your submission on Prolific by selecting the 'Stop without completing' button."
                                    ) .print() 
                         )
                        )

    Thanks, Jeremy!

    Best,
    Daniela

    #9709
    nasimbhmn
    Participant

    Hi Jeremy,

    I am asking my question here because it is relevant to this topic.
    I have two questions on a single page and I want to give a warning to participants if they left any of them unanswered before they proceed to the next page. I want the warning message to appear below the question that is unanswered. Everything seems to be working except that if people answer the second question and only forget about the second question, both warning messages appear. It works fine the other way around though.

    Here is my code. Could you please help me find the problem?

    
    newTrial("trial1", 
        newText("Question 1")
            .print()
        ,
        
        newScale("scale1",5)
                .before( newText("left", "(<em>totally natural</em>)").css("font-size", "small") )
                .after( newText("right", "(<em>totally unnatural</em>)").css("font-size", "small") )
                .labelsPosition("top")
                .size(200)
                .css("max-width", "unset")
                .left()
                .log()
                .print()
        ,
        
        newText("<br><p>Question 2</p>")
            .print()
        ,
        
        newScale("scale2",  "yes", "no", "I'm not sure")
            .radio()
            .labelsPosition("right")
            .vertical()
            .print()
            .log()
            // .wait("first")
        ,
        
        newButton("proceed","click here to continue")
            .cssContainer({"margin-bottom":"3em"})
            .cssContainer({"margin-top":"3em"})
            .print()
            .wait( 
                getScale("scale1")
                .test.selected()
                .failure(newText("required1")
                        .css("position", "relative")
                        .css("bottom", "270px")
                        .bold().color("red").print())
                .and(
                getScale("scale2")
                .test.selected()
                .failure(newText("required2")
                    .css("position", "relative")
                    .css("bottom", "100px")
                    .bold().color("red").print())
                    )
            )
    )
    

    Thanks a lot in advance!
    Best, Nasim

    #9710
    Jeremy
    Keymaster

    Hi Nasim,

    When you use and on a test command, its success and failure will be executed in response to the conjunction, not to the main test alone

    One workaround is to embed each test inside a higher-up conjunction, eg:

    .wait( 
        newFunction( ()=>true ).test.is(true)
            .and( getScale("scale1").test.selected().failure(
                newText("required1").css({position:"relative",bottom:"270px"}).bold().color("red").print()
            ) )
            .and( getScale("scale2").test.selected().failure(
                newText("required2").css({position:"relative",bottom:"270px"}).bold().color("red").print()
            ) )
    )

    Jeremy

    #9711
    nasimbhmn
    Participant

    Hi Jeremy,

    That’s a great solution. Thanks a lot.

    Best, Nasim

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.