Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Supported by

[solved] Custom forms: How to activate a 'Next Button' only when a checkbox is chosen

edited April 2015 in OpenSesame

Hi,

I created a custom form with an inline python script. On the form there are some multiple choice checkbox widgets and a next button.
Currently, a participant can click 'Next' without having checked any of the answers/checkboxes. How can I achieve that the 'Next Button' is only active/clickable if a choice is made?

Best,
Johannes

Comments

  • edited 1:41AM

    Hi Johannes,

    It seems that there is no simple option or command to take care of this directly (based on http://osdoc.cogsci.nl/forms/form-variables/#in-custom-forms)

    However, when no choice was made, the my_response_var would be set to 'no', and you can use this to your advantage. Basically, you would place your custom form in a loop item. In the loop item, check the 'advanced options' box and insert the Break if command:
    =self.get('my_response_var') != 'no'. Thus, the custom form would be repeated until there is something else than a 'no'.

    Of course it might be nice to add a copy of the custom form to the loop (so both forms would have to go in a sequence item that itself is placed in a loop item), with the addition of a text line such as "Please choose an option!", and for the second form insert the run-if command: =self.get('my_response_var') == 'no'.
    Additionally, you would need to make an inline script (placed outside of the loop) with some code to make sure the first form isn't run if the second form is run. You can do this by making a variable, e.g. 'CHECK' and set it to False, and then write code (this time IN the loop) to set it to True if my_response_var == 'no'. Next, for the first form you would have to insert the run-if command: =self.get('CHECK') == False.

    So what would happen now, is that people see a form, and if they click a button without choosing an option, a text will appear that says "Please choose an option!". The screen will only disappear (i.e. we would break out of the loop) if an option is chosen!

    Hope this helps!

    Cheers,

    Josh

  • edited 1:41AM

    Hi Josh,

    Thanks for your help.
    I tried this, but my experiment nevertheless either just proceeds if the next button is pressed or it just quits (i.e. the break command ends the loop, but the loop does not run again). Here is a minimal working example:

    # Generated by OpenSesame 2.9.4 (Hesitant Heisenberg)
    # Mon Mar 30 17:14:45 2015 (posix)
    # <http://www.cogsci.nl/opensesame>
    
    set background "#aaffff"
    set bidi "no"
    set canvas_backend "xpyriment"
    set compensation "0"
    set coordinates "relative"
    set description "Default description"
    set font_bold "no"
    set font_family "mono"
    set font_italic "no"
    set font_size "18"
    set foreground "#550000"
    set height "768"
    set keyboard_backend "legacy"
    set mouse_backend "xpyriment"
    set sampler_backend "legacy"
    set start "experiment"
    set subject_nr "0"
    set subject_parity "even"
    set synth_backend "legacy"
    set title "New experiment"
    set width "1024"
    
    define inline_script _inline_script
        set _prepare ""
        set _run "exp.set('my_response_var_2','no')"
    
    define loop _loop
        set break_if "[my_response_var_2]!='no'"
        set column_order ""
        set cycles "1"
        set item "inline_script"
        set order "sequential"
        set repeat "1"
        set skip "0"
        run inline_script
    
    define sequence experiment
        run _inline_script "always"
        run loop "always"
    
    define inline_script inline_script
        set _prepare ""
        ___run__
        # Import the widgets library
        from libopensesame import widgets
    
        option1 = self.get('choice1')
        option2 = self.get('choice2')
    
        # Create a form (margins order: top,right,bottom,left)
        form = widgets.form(self.experiment, cols=[1,1,1,1], rows=[6,1,1,1,1,1,1], margins=(10,10,10,10), spacing=10)
    
        # Create widgets
        checkbox1 = widgets.checkbox(form, text=option1, group='group', var='my_response_var_2')
        checkbox2 = widgets.checkbox(form, text=option2, group='group', var='my_response_var_2')
        nextbutton = widgets.button(form, text='Next', center=True, var='next_button_clicked')
    
        # Add the widgets to the form. The position in the form is indicated as a (column, row) tuple.
        form.set_widget(checkbox1, (1,2),colspan=2)
        form.set_widget(checkbox2, (1,3),colspan=2)
        form.set_widget(nextbutton, (0,6),colspan=4)
    
        # Display the form
        form.render()
    
        # Evaluate the form
        form._exec()
        __end__
    
    define logger logger
    
    define loop loop
        set break_if "never"
        set column_order "choice1;choice2"
        set cycles "2"
        set item "sequence"
        set order "sequential"
        set repeat "1"
        set skip "0"
        setcycle 0 choice1 "text1"
        setcycle 0 choice2 "text2"
        setcycle 1 choice1 "text3"
        setcycle 1 choice2 "text4"
        run sequence
    
    define sequence sequence
        run _loop "always"
        run logger "always"
    
    

    Could you indicate to me where I am going wrong?

    Thank you,
    Johannes

  • edited 1:41AM

    Hi Johannes,

    I can't tell you why your script isn't working, because OpenSesame doesn't allow me to import it for some strange reasons, but I suspect the reason could be related to the prepare-run phases. In any way, here is a small example of a script that should do what you want it to.
    Let us know, if there are other problems.

    Eduard

  • edited April 2015

    Hi Eduard,

    Thank you for providing this example script. My misunderstanding was that I tried to solve the problem by using nested loops.

    I now tried out your example script and I have some questions. So what happens is the following:

    I start the script and if I do not select a checkbox it processes a second loop which is essentially a copy of the first but with a warning message and a break if condition. I guess you have added the second, different row in the second loop to make the processing just more visible?

    However, if I do not select anything, the experiment ends after 3 cycles. That's because the second is repeated 3 times. That would be bad in a real experiment, as the first loop would just not be processed anymore, no matter if there are still lines in it.

    Thus, my questions are:

    1) To be totally sure that a participant cannot accidentally end the experiment I would need to set the repeat value of the second loop to a very high number?

    2) I initially thought that internally/behind the GUI of OS the break if condition would turn the for loop of a loop item into a while loop. But this does not seem to be the case. But with a while loop I could achieve an potentially endless processing until a break condition is met, couldn't I? Is this possible via the GUI only?

    3) If my first loop item has 20 lines from which OS chooses randomly, how can I make sure that OS chooses the same line in the second loop that was chosen in the first loop and repeats only this line and does not go on with the next line in the second loop?

    Best,
    Johannes

    Update

    Thanks to Eduards comment in another thread I managed to get a working solution by using a python inline script.

    I just used a separate form.render() followed by a final form.exec() call. I enclosed the form.render() in a while True: loop with a break if condition that is met only when the checkbox response variable was !='no'. That did the trick.

    However, I am still unsure if this would be also possible using the GUI and I'd like to know what the break if in the advanced loop options is doing behind the scenes.

    Johannes

  • edited 1:41AM

    Hi Johannes,

    Nice to hear that it works now. But just for sakes of completeness here the things that I know:

    I guess you have added the second, different row in the second loop to make the processing just more visible?

    Yes. I haven't work much with forms yet. So, I just copied your code a bit to check things out.

    1) To be totally sure that a participant cannot accidentally end the experiment I would need to set the repeat value of the second loop to a very high number?

    Right. I chose a value of three, just to test the script and don't have to repeat it forever

    2) But with a while loop I could achieve an potentially endless processing until a break condition is met, couldn't I? Is this possible via the GUI only?

    I'm not super sure, but I think there is no while loop possible with the GUI loop items. Every time when other users had similar problems, for which while loops were a solution, Sebastiaan's suggestion was to use an absurdly high value of repeats that creates virtually a while loop. I suppose @Sebastiaan, can tell you more about this matter, if wished.

    how can I make sure that OS chooses the same line in the second loop that was chosen in the first loop and repeats only this line

    I haven't tried it myself, but I think you could create the second loop in a way, that it doesn't provide any new information to the form. What I mean is that the all information that you need to built the form (e.g. your 'text1' variable, if I remember right), are not provided by the second loop, but passed on from earlier in the experiment, i.e. the first loop and its elements. So basically, the second loop is in a sense empty and merely a wrapper around your form. Do you understand, what I am trying to explain?

    I hope this cleared things up.

    Eduard

  • edited February 11

    Hey there, I am facing the same challenge Johannis did about 2 years ago. I have a form item where participants use a rating scale to evaluate a stimulus. I would like that participants are only able to proceed once they have provided an answer. If the "next" button is pressed without filling in the rating scale, I would like the same stimulus to be repeated, with the note "Please provide an answer" (as mentioned above).
    By now the link eduard provided to a small script with a solution is dead, and without it it is too difficult for me to understand this thread. Could you repload the sample script somewhere?

  • Hi Mati,

    OpenSesame 3.2 allows you to validate form input, so the solution posted above is no longer necessary. See here:

    Cheers!
    Sebastiaan

    There's much bigger issues in the world, I know. But I first have to take care of the world I know.
    cogsci.nl/smathot

Sign In or Register to comment.