PennController for IBEX › Forums › Support › Getting variable from csv, based on DropDown selections
- This topic has 4 replies, 2 voices, and was last updated 3 years, 4 months ago by
bta.
-
AuthorPosts
-
July 25, 2022 at 11:51 am #8309
btaParticipantI 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 #8312
JeremyKeymasterHi,
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
varForImgvariable, it creates thesetvarForImgandgetvarForImgfunctions, it sets theSequence, it creates the trial labeled"whoareyou", and runs theTemplatefunction to create as manynewTrials as there are lines in fullList.csv. Because you callsetvarForImg9 times in thatnewTrialfunction, it is called 9 times with eachnewTrialcreation, and when the script gets tonewImage("comicstrip", varForImg)when creating a trial, the value ofvarForImgis always set to the value ofvariable.P3C, because that’s the value passed to the most recently executedsetvarForImgfunctionThen, 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 theP3Ccell for the row from which the trial was created. The first PennController commands to be run as you start a new trial are thetests on the Var element, whosesuccesscommands have no actual effect (becausesetvarForImgreturnsundefined, whichsuccesswill simply ignore:undefinedis not a PennController command). When the trial’s execution reaches the Image element, it will simply display the the file referenced in theP3Ccell, regardless of the earliertestsWhat you can do instead is delete all references to
varForImg(including the javascript functions) and include all 9 possiblenewImagecommands in the trial (then PennController will effectively create, and preload, all 9 Image elements per trial) but only execute one of those in thetests 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 #8314
btaParticipantOh 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.isstatements every time I reuse the image. Is that right?
(i.e., it seems to me that all of thesenewImages cannot have the same name —something like testerImage— because every timenewImageis 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 #8315
JeremyKeymasterHi,
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 #8316
btaParticipantThank 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.