PennController for IBEX › Forums › Support › Getting variable from csv, based on DropDown selections
- This topic has 4 replies, 2 voices, and was last updated 2 years, 4 months ago by bta.
-
AuthorPosts
-
July 25, 2022 at 11:51 am #8309btaParticipant
I have a CSV with multiple columns, and I want my template to run trials using different columns depending on DropDown selections.
To be clearer: I start off asking the participant to select from two DropDown lists, and I’m able to create variables that has that information, and then I try to use a (javascript) variable as the input to a “newImage” construct. And it seems to work — images come up from the CSV! BUT the problem is that the script always pulls values from the last column in the CSV, instead of from the column corresponding to the header text stored in the variable.
Here’s an example:
https://farm.pcibex.net/r/zObmeL/Any thoughts on what’s going on here?
July 25, 2022 at 1:28 pm #8312JeremyKeymasterHi,
Javascript is immediate, PennController is delayed. More specifically, you cannot dynamically pass values to
newImage
(also, how would PennController be able to preload the image file if it had to wait until the trial starts to know which file to use?)What happens in your case is, as soon as the experiment page is open, all the javascript code is executed immediately (top down). First it creates the
varForImg
variable, it creates thesetvarForImg
andgetvarForImg
functions, it sets theSequence
, it creates the trial labeled"whoareyou"
, and runs theTemplate
function to create as manynewTrial
s as there are lines in fullList.csv. Because you callsetvarForImg
9 times in thatnewTrial
function, it is called 9 times with eachnewTrial
creation, and when the script gets tonewImage("comicstrip", varForImg)
when creating a trial, the value ofvarForImg
is always set to the value ofvariable.P3C
, because that’s the value passed to the most recently executedsetvarForImg
functionThen, when you progress through the experiment, as you get to a trial labeled
"demo"
, that trial already contains an Image element named"comicstrip"
that points to a file whose name is the value in theP3C
cell for the row from which the trial was created. The first PennController commands to be run as you start a new trial are thetest
s on the Var element, whosesuccess
commands have no actual effect (becausesetvarForImg
returnsundefined
, whichsuccess
will simply ignore:undefined
is not a PennController command). When the trial’s execution reaches the Image element, it will simply display the the file referenced in theP3C
cell, regardless of the earliertest
sWhat you can do instead is delete all references to
varForImg
(including the javascript functions) and include all 9 possiblenewImage
commands in the trial (then PennController will effectively create, and preload, all 9 Image elements per trial) but only execute one of those in thetest
s on the Var element:Template("fullList.csv", variable => newTrial("demo", newText("head", " ") .text(getVar("asdf")) .before(newText("b","").text(getVar("namelist")).after(newText(": "))) .center() .print() , defaultImage.center().print() , getVar("namelist") .test.is("P1A").success( newImage(variable.P1A) ) .test.is("P1B").success( newImage(variable.P1B) ) .test.is("P1C").success( newImage(variable.P1C) ) .test.is("P2A").success( newImage(variable.P2A) ) .test.is("P2B").success( newImage(variable.P2B) ) .test.is("P2C").success( newImage(variable.P2C) ) .test.is("P3A").success( newImage(variable.P3A) ) .test.is("P3B").success( newImage(variable.P3B) ) .test.is("P3C").success( newImage(variable.P3C) ) , newButton("moveOn", "Continue") .center() .print() .wait() ) )
Jeremy
July 26, 2022 at 2:22 pm #8314btaParticipantOh great, thanks! This is very helpful. I did not know that all JS functions are run from the start, even when the calls to those functions are made within instances of PennController
test.is
.The one thing that I didn’t mention before is that I did want to reuse the image multiple times, which I think would just mean using the series of
test.is
statements every time I reuse the image. Is that right?
(i.e., it seems to me that all of thesenewImage
s cannot have the same name —something like testerImage— because every timenewImage
is called it needs to have a unique identifier; and because of that, there’s no way to use a single line of code likegetImage("testerImage")
to call back that same image.)July 26, 2022 at 3:04 pm #8315JeremyKeymasterHi,
You could print the image onto a Canvas element, and manipulate that one Canvas element instead—I don’t think there’s anything you can do on an Image element you cannot do on a Canvas element:
Template("fullList.csv", variable => newTrial("demo", newText("head", " ") .text(getVar("asdf")) .before(newText("b","").text(getVar("namelist")).after(newText(": "))) .center() .print() , newCanvas("image").center().print() , getVar("namelist") .test.is("P1A").success( newImage(variable.P1A).print(getCanvas("image")) ) .test.is("P1B").success( newImage(variable.P1B).print(getCanvas("image")) ) .test.is("P1C").success( newImage(variable.P1C).print(getCanvas("image")) ) .test.is("P2A").success( newImage(variable.P2A).print(getCanvas("image")) ) .test.is("P2B").success( newImage(variable.P2B).print(getCanvas("image")) ) .test.is("P2C").success( newImage(variable.P2C).print(getCanvas("image")) ) .test.is("P3A").success( newImage(variable.P3A).print(getCanvas("image")) ) .test.is("P3B").success( newImage(variable.P3B).print(getCanvas("image")) ) .test.is("P3C").success( newImage(variable.P3C).print(getCanvas("image")) ) , newButton("Flicker") .center() .print() .wait() .remove() , getCanvas("image").remove() , newTimer(2000).start().wait() , getCanvas("image").print() , newButton("Finish").center().print().wait() ) )
Jeremy
July 27, 2022 at 3:40 pm #8316btaParticipantThank you so much, this is so helpful! I find it challenging to think this way, but I’m starting to get used to it.
-
AuthorPosts
- You must be logged in to reply to this topic.