PennController for IBEX › Forums › Support › Multi Character Key Press
- This topic has 2 replies, 2 voices, and was last updated 4 years, 10 months ago by
samsanto.
-
AuthorPosts
-
April 29, 2020 at 10:59 pm #5178
samsanto
ParticipantHi Jeremy,
I was wondering if there was a way to use one Key element to gather multiple characters of user input at once (a sentence for example). I need the user to input a string of characters, but there is no way to guarantee the string’s length (so I can’t use say, 6 individual elements and just wait on each). I also need to be able to validate that string immediately afterwards with a value from a table. The user cannot see what they are typing and are not able to edit their response (thus the need for Key element, rather than a simple Text Input Box).
So far, I have the following code, but it doesn’t work:
Template( "fulldesign.csv" , variable => newTrial( "task" , newVar("guess") , newText("fullString","") , //somehow concat all key-presses into one text newKey("keys","qwertyuio") .setVar("guess") .callback( getText("fullString").after(newText().text(getVar("guess"))) ) // stop when enter is pushed newKey("stop","Enter").wait() , getText("fullString").test.text(variable.answer) .success(//do stuff) .failure(//do stuff) )
Any help, ideas, or alternate solutions would be greatly appreciated!
Thanks so much,
SamApril 30, 2020 at 12:01 pm #5179Jeremy
KeymasterHi Sam,
EDIT: actually you don’t have to use the Function element as I suggest below, but you’ll still need a little bit of javascript when setting and testing your Var element:
Template( "fulldesign.csv" , variable => newTrial( "task" , newVar("fullstring", "") , newText("Please type your guess").print() , newKey("guess", "") .callback( getVar("fullstring").set( v=>v+getKey("guess").value ) ) , newKey("Enter").wait() , getVar("fullstring").test.is( v=>v.match(new RegExp(variable.answer+"$","i")) ) .success( newText("Correct!").print() ) .failure( newText("Incorrect").print() ) , newButton("next").print().wait() ) )
End of edit
I think you’ll have to inject some javascript in there, using the Function element:
Template( "fulldesign.csv" , variable => newTrial( "task" , newText("Please type your guess").print() , newFunction(function(){ this.fullstring = ""; let oldOnkeydown = document.onkeydown; document.onkeydown = e=>{ if (oldOnkeydown instanceof Function) oldOnkeydown.call(document, e); this.fullstring += e.key; }; }).call() , newKey("Enter").wait() , newFunction(function(){ return this.fullstring.match(new RegExp(variable.answer+"$","i"))!=null; }).test.is( true ) .success( newText("Correct!").print() ) .failure( newText("Incorrect").print() ) , newButton("next").print().wait() ) )
Two comments on your code:
- The setVar command (as all PennController commands) is executed immediately when the script encounters it, so unless it is in a callback command, it will only be executed once. In your case, you call it immediately after creating the Key element, so your Var element will remain empty.
- The after command adds an element to the right of another element when printed on the page, but it does not change the value of either element
Jeremy
-
This reply was modified 4 years, 10 months ago by
Jeremy. Reason: Added a Function-less script
April 30, 2020 at 2:27 pm #5181samsanto
ParticipantHi Jeremy,
This works great! Thank you so much, I really appreciate you taking the time.
-S
-
AuthorPosts
- You must be logged in to reply to this topic.