Error in adding free-ranging participant text to online experiment

I would keep your screen units the same, it is not a good idea to start mixing units because they do not correspond with one another. Either use all “Norm” or all “Height”. If you read the link regarding units, you will get an understanding of how to size your units correctly. For example, if your screen units are height, everything is specified relative to the height of the window, where .5 is the top of the screen, and -.5 is the bottom of the screen, in height units. Text will need to be sized accordingly, e.g., size your text as .1 (1 tenth of the height of the screen).

Hi @dvbridges , Thanks for all the feedback. I changed all the experiment settings to norm, as you recommended. The experiment hangs on the first question and doesn’t allow me to enter text (in builder). And when I try to upload it online (using 3.0.6), somehow Im running into a syncing error: “None points to a remote that doesn’t exist (deleted?). What shall we do?”

I tried to upload an old experiment that worked both in builder and online, and I’m getting the same error. I selected “New” under “Pavlovia.org” in headings to upload it. The new experiment’s name shows up on Pavlovia but with no other files and it says “The repository for this project is empty”. I’m not sure where Im making a mistake here. Any help would be much appreciated.

Hi @dvbridges
I was able to upload the experiment and run it online by changing the location of exp (though not 100% certain that’s the reason). In builder, I cannot type text, but when uploaded online it allows me to type text but it doesn’t move to the next question after pressing enter. It types ‘return’ every time I press enter.

I thought this JS code helps this issue. I tried both “frameEnded” and “routineEnded” and they both yield similar results.

}
// check for return (move to next frame):
if (theseKeys.indexOf('return') > -1) {
    psychoJS.experiment.frameEnded = true;
}

(or frame)

Great, glad it is mostly working now. If you want to run the experiment from Builder, you have to make sure that you have the Python code that updates your text onscreen. You can see both Python and JavaScript side by side if you set the Code Type in the code component as “Both”.

To stop the keypresses like ‘return’ and ‘space’ from being printed on screen, you have to change what is added to the temporary textAdd variable. In the example below, return resets the text variables and ends the trial. E.g.,

if (theseKeys.indexOf('return') > -1) {
    textAdd = '';  // Add nothing
    text.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)
} else if (theseKeys.indexOf('space') > -1) {
    textAdd = ' ';  // Add a space
}

You will also want to capture shift etc and make sure they are not printed on screen

Hi @dvbridges
I was able to stop the keypresses like shift as well! Thank you for your help/patience as I navigated this process. I learned a great deal and it is much appreciated.
Mira

1 Like

Hi @dvbridges
Sorry to circle back again about this. Everything works smoothly now, but the participant’s .csv output file doesn’t include the free-range text data.

I came across a thread with the code to save, but it’s in python (for Builder).

I tried to convert it to JS using online examples, but it’s not working. Would you please help me with this part as well?

if (textAdd) {
        thisRoutine.addData;
       }

Many thanks,
Mira

Hi @wheights01, try the following:

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

Hi @dvbridges
Thank you for the quick reply. I added this code to the exp, and when I run it online, the page shows “loading experiment…” and it doesnt move forward.

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

Also, I added the code under “Each Frame”, I wasn’t sure if it needs to go under “End Routine” or “End Experiment”

Best
Mira

I fixed one error @dvbridges , changing the second text to “text_check1” as this is what its named in my experiment, but Im still getting the same message. I also tried running the experiment with this code under “Each Routine”, and no luck.

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

Thanks a bunch for your help.

Hi, would you mind sharing the URL to your task?

Here it is:
https://pavlovia.org/run/elmiraraeifar/andersen391/html/

Ok, first thing to change is where you save data. Take out the code for saving data from the “Each Frame” tab, this would save data on every frame, or 60 times a second on a 60Hz monitor. In the same block of code in the “Each Frame” tab, make sure that your curly braces close correctly. It looks like you are missing the closing brace } from the block of code used to write the input on screen.

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.