Create several clickable text input fields

OS: Win10
PsychoPy version: 3.0.6
Standard Standalone? (y/n): yes
What are you trying to achieve?: Create several clickable text input fields within a same routine.

Hello!

I am trying to crate a kind of survey.

I display a question which has to be answered in a field. I used the following code component and a text component to display the answer:

Begin Routine

cursorCounter=0
cursorVariable='|'
captured_string=''
subject_response_finished=False
trial_clock=core.Clock()

Each frame

if cursorCounter >= 30:
    if cursorVariable=='|':
        cursorVariable=' '
    else:
        cursorVariable='|'
    cursorCounter=0
cursorCounter+=1
if trial_clock.getTime() >= 1:
    subject_response_finished=True

if subject_response_finished:
    final_response=captured_string
for key in event.getKeys():
    if key in ['escape']: 
        core.quit()
    elif key in ['delete','backspace']:
        captured_string = captured_string[:-1] 
    elif key in ['space']:
        captured_string = captured_string+' '
    elif key in ['lshift','rshift','up','down','left','right']:
        pass
    else: 
        captured_string = captured_string+key

End Routine

thisExp.addData('response',final_response)

(I wish I could cite the source of this code but I can’t find it…)

Then because I wanted a second input text field, I did the same within another code component and another text component, just changing the name of captured_string, final_response and subject_response_finished

It didn’t work. The second text component (where the second text input should appear) works at the same time as the first, and the characters that appears in the second text component are randomly selected from the typed sequence.

Then I added in Begin experiment mouse.isPressedIn(something) so that the code understands that there are 2 different questions to answer. It didn’t work, my experiment won’t run.

I would be so glad if someone could help me!!! Thanks a lot in advance.
Oceane.

Hi @Oceane, try the following. It is a simplified version of your code, it just shows text components that you can click. You cannot click empty text components because they have no size, but if you fill them beforehand with generic text (e.g., "Click here to enter text..."), you can click them to make them the current text box (component).

##### Begin Routine #####

currentText = text
captured_string = ''
textComps = [text, otherText]  # list your clickable text components

def checkText(text):
    # Clear generic text and return text component
    if text.text == "Click to enter text...":
        text.text = ''
    return text
     
def refillEmpty(currentText):
    # If text box empty when another one is clicked, 
    # this function refills the text so it 
    # can be clicked again
    for text in textComps:
        if text != currentText and len(text.text) == 0:
            text.text = "Click to enter text..."

###### Each Frame #####

for eachText in textComps:
    if mouse.isPressedIn(eachText):
        currentText = checkText(eachText)
    
for key in event.getKeys():
    if key in ['escape']: 
        core.quit()
    elif key in ['delete','backspace']:
        captured_string = captured_string[:-1] 
    elif key in ['space']:
        captured_string = captured_string+' '
    elif key in ['lshift','rshift','up','down','left','right']:
        pass
    else: 
        captured_string = captured_string+key
 
currentText.text += captured_string  # Add key press to text component
captured_string = ''  # Clear captured_string after each key press

# Check that text can be clicked
refillEmpty(currentText)

Here is the actual example…
multiText.psyexp (9.5 KB)

Thank you so much! Problem solved. Have a nice day!
Oceane.

@dvbridges , excuse me to bother you again but the line elif key in ['delete','backspace']: captured_string = captured_string[:-1] doesn’t work (i.e., it doesn’t delete any character). It is the same in my previous experiments.

Does it work for you? Is it a bug?
Oceane.

No bother, and yes it needs a fix, just replace with

elif key in ['delete','backspace']:
    if len(currentText.text) > 0:
        currentText.text = currentText.text[:-1]
elif key in ['space']:
        captured_string = ' '

Also, if you ever want to see an example of text input for both local and online tasks, see:

https://run.pavlovia.org/demos/textinput/html/
https://gitlab.pavlovia.org/demos/textinput

Thanks much David! I really need to learn Python :grimacing:

Hi David, I’m trying to insert a text entry box for participants to type in their unique ID, this will happen just once at the beginning of the experiment. I tried to use the code component provided in your textInput experiment, but the text I typed will only show up once I clock past the instruction page where they would have made the typing. How should I fix the code so that participants can see while they are typing? is there a way to simplify the code since I’m not running loops

Hello - I am able to implement this code in the builder but am having trouble getting it to work online. I think it may be with the python to JS translation. Can you please provide any help or sources where this is implemented successfully online?

Thanks!