Error in adding free-ranging participant text to online experiment

Thanks David, I made those changes and still getting the same message. Just to be sure I got the closing brace correctly:
Under “Each Frame”:

let theseKeys = psychoJS.eventManager.getKeys();
if (theseKeys.length > 0) {  // at least one key was pressed
  textAdd = theseKeys[theseKeys.length-1]; 
  }


// check for quit:
if (theseKeys.indexOf('escape') > -1) {
    psychoJS.experiment.experimentEnded = true;
}
if (theseKeys.indexOf('return') > -1) {
    textAdd = '';  // Add nothing
    text_check1.setText('')  // empty the onscreen text ready for next input (just be sure to save it)
    continueRoutine = false;  // End routine (if that is what you want)
}

if (textAdd) {
    if (theseKeys.indexOf('space') > -1) {
        text_check1.setText(text_check1.text + " ");  
        textAdd = undefined;
    } else if (theseKeys.indexOf('backspace') > -1) {
        text_check1.setText(text_check1.text + textAdd[textAdd.length-1]);  
        textAdd = '';  // Add nothing
        text_check1.setText('')  // empty the onscreen text ready for next input (just be sure to save it)
    } else if (theseKeys.indexOf('lshift') > -1) {
        text_check1.setText(text_check1.text + " ");  
        textAdd = undefined;
    } else if (theseKeys.indexOf('rshift') > -1) {
        text_check1.setText(text_check1.text + " ");  
        textAdd = undefined;
    } else {
        text_check1.setText(text_check1.text + textAdd);  
        textAdd = undefined;
}

And under “End Routine”:

if (textAdd) {
    psychoJS.experiment.addData('textInput', text_check1.text);
}

I think there is still a missing brace above. Try

...
} else {
        text_check1.setText(text_check1.text + textAdd);  
        textAdd = undefined;
 }
}

Great. Now the experiment is running again, but the data is still not being saved :confused:

Is there anything else I can try or perhaps re-check?

Yes, try removing the conditional that decides whether to save. Instead, always save the contents of the text component at the end of the routine:

psychoJS.experiment.addData('textInput', text_check1.text);

Sorry, I’m having a hard time following. All my text components are under “Each Frame”, not “Each Routine”. Do you mean I should leave all my text component codes as is (under Each Frame) and include only the line below under “End Routine”?

psychoJS.experiment.addData('textInput', text_check1.text);

Ah your text component is emptied every time you press return to end the trial, so no text will be available at the end of the routine. You need a slight reorganisation of your code:

Each Frame

// Change what happens when the trial is ended, by storing the text in a temp variable
if (theseKeys.indexOf('return') > -1) {
    textAdd = '';  // Add nothing
    tempText = text_check1.text;  // get the text from the text component
    text_check1.setText('');  // empty the onscreen text ready for next input (just be sure to save it)
    continueRoutine = false;  // End routine (if that is what you want)
}

End Routine

// save text
psychoJS.experiment.addData('textInput', tempText);

Ah my output is now saving the text from the second question (text_check2) :slight_smile: but not the first question.
I have two questions and text components: text_check1 and text_check2. I added the above code to Each Frame and the End Routine for both. Did I understand you correctly?

Thanks again for your help, I appreciate it so much.

Would you mind sharing your task? I cannot tell what is happening without seeing your code.

Sorry to trouble you this much about one task. Here is my task:andersen398.psyexp (14.8 KB)
textInputTest.xlsx (8.5 KB)

Its no problem! The first thing I notice is that your column names for each text input are the same (i.e., for check1 and check2). I think that check1 is written, but then overwritten by check2. Try giving your data columns different names for each text input e.g.,

// for check1, 
psychoJS.experiment.addData('check1_Text', tempText);

Then for check2

psychoJS.experiment.addData('check2_ Text', tempText);

Thank you David, now I have two columns (check1_text and check2_text) in my output file, but the first column is empty and the entered text only shows for the second column.

Have you added the tempText variable container to the code_check1 code?

Yes, but I caught another typo. And now it’s working, I have data in both columns :smile:

I cant thank you enough for all your help @dvbridges

1 Like

Hi @wheights01 @dvbridges

I’ve followed this code and my experiment is working online. The only problem is that I’m not able to use the backspace to actually delete the last character. Here is my code.
Any help is really appreciated.

‘’’
if (textAdd) {
if (theseKeys.indexOf(‘space’) > -1) {
text.setText(text.text + " ");
textAdd = undefined;
} else if (theseKeys.indexOf(‘backspace’) > -1) {
text.setText(text.text + textAdd[textAdd.length-1]);
textAdd = undefined;
} else if (theseKeys.indexOf(‘lshift’) > -1) {
text.setText(text.text + " ");
textAdd = undefined;
} else if (theseKeys.indexOf(‘rshift’) > -1) {
text.setText(text.text + " ");
textAdd = undefined;
} else {
text.setText(text.text + textAdd);
textAdd = undefined;
}

@viviana_greco, I think you will want to reduce the text in the text component by 1, rather than textAdd, so try:

} else if (theseKeys.indexOf(‘backspace’) > -1) {
text.setText( text.text.slice(0, text.text.length - 1) );
//...

Hi @dvbridges,

Thank you very much. All working now!!

Hi, this works perfectly (although the file you shared is expired).

This is the link for my experiment: https://run.pavlovia.org/laurapissani/type_simple/html/

Everything works except: return to force quit (although I could add another keyboard component to force routine. But can you please help me to add BACKSPACE and SHIFT to this code you wrote, please.

let theseKeys = psychoJS.eventManager.getKeys();
if (theseKeys.length > 0) {  // at least one key was pressed
  textAdd = theseKeys[theseKeys.length-1]; 
  }

// check for quit:
if (theseKeys.indexOf('escape') > -1) {
    psychoJS.experiment.experimentEnded = true;
}
// check for return (move to next frame):
if (theseKeys.indexOf('return') > -1) {
    psychoJS.experiment.routineEnded = true;
}
if (textAdd) {
    if (theseKeys.indexOf('space') > -1) {
        text.setText(text.text + " ");  
        textAdd = undefined;
    } else if (theseKeys.indexOf('backspace') > -1) {
        text.setText(text.text + textAdd[textAdd.length-1]);  
        textAdd = undefined;  
    } else if (theseKeys.indexOf('shift') > -1) {
        //how to shift a character?  
        textAdd = undefined;  
    } else {
        text.setText(text.text + textAdd);  
        textAdd = undefined;
    }
}

Try continueRoutine = False (Python) which translates to continueRoutine = false; (JS) to end the routine.

For upper case I think it’s .upper() which translates to .toUpperCase() but I might have the syntax wrong there. Try searching the forum for toUpperCase

Thank you, the continueRoutine = false worked, but the .toUpperCase() didn’t, I don’t know the full formula… what else do I add?

   } else if (theseKeys.indexOf('shift') > -1) {
        .toUpperCase()
        textAdd = undefined;

What are you putting to upper case? If it’s textAdd then I think it should be textAdd.toUpperCase() and you should remove the following line making it undefined.

I know I’ve seen the code for this on the forum but I might be misremembering it. However, I do know that this is in my crib sheet so you can add something to code_JS so the auto translate works with .upper

Search the forum for a link to my crib sheet