Forum Replies Created
-
AuthorPosts
-
Jeremy
KeymasterHi Irene,
I’ve unfortunately been unable to reproduce the problem so far. Would you mind opening your javascript console (https://www.techonthenet.com/js/open_console_log.php) and check whether you see any error message in those cases when sending the results fails? (don’t mind the warning messages about 404 errors)
If you see something about controllers.running being undefined then it means I’ve (partly) identified the problem.
Thanks,
JeremyJeremy
KeymasterHi Anne,
Whether your server is a VM should not make a difference, as long as you run Apache+PHP on it, just pass the link to your php script to InitiateRecorder—although keep in mind that you will need a secure domain (https), so a public IP address won’t be enough for that
Same thing about the audio: as long as you have a public link that points to a valid audio file, it should work just fine
Jeremy
Jeremy
KeymasterHi,
There’s no bulletproof method to ensure that someone is using a desktop rather than a phone or a tablet, but there are good approximation methods.
One option is to check the width of the screen:
newTrial( newFunction( ()=>window.matchMedia("only screen and (max-width: 760px)").matches ) .test.is(true) .success( newText("<p>We're sorry but this experiment requires a wider resolution.</p>"+ "<p>Please do not use a modile device to take this experiment.</p>"+ "<p>If you are using a desktop browser, make sure to maximize this window.</p>") .print() , newButton().wait() ) )
Another solution is to use user agent sniffing:
newFunction( ()=>navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i) ) .testNot.is(null)
Jeremy
Jeremy
KeymasterHello Susanne,
Unfortunately there currently is no password-reset function on the Farm, nor is there a tutorial on the dashed sentence controller. Feel free to send an email to support@pcibex.net with your Farm username and details (approximate time of registration, list of projects on the account as you remember them) and I’ll reset the password for you. You can look at this documentation to learn more about the options of the DashedSentence controller.
Jeremy
Jeremy
KeymasterI’ll have to spend more time on this and be able to replicate the problem before I can (try to) fix it
In the meantime, can you try this hack? Replace you Sequence command with this:
Sequence( sepWith("trytoquit" , seq( 'introduction',"checkloadings-introExp", 'callibration','checkloadings-fam','instructions','checkloadings-introTest',"startRecording",'consent','checkloadings-test',"important-points","getkid", 'introExp','familiarization', 'sendrecords', 'introTrials', sepWith("sendrecords",'test_trial'),'sendrecords-end','bye' ) ) ) //order of trials
Add this to your Header:
newVar("shouldquit",false).global()
And add this trial to your script:
newTrial( "trytoquit" , getVar("shouldquit").test.is(true).success( SendResults() , clear() , newButton().wait() ) )
Then replace your SendResults command (and the following commands) in your success commands with this:
getVar("shouldquit").set(true),end()
This way, your script will try to quit the experiment early after every single trial, but will effectively do so only if the shouldquit Var element is true, ie. only after a click on the Sortir button.
Hopefully this should fix the main problem (I think the corrupted file is unrelated)
Jeremy
Jeremy
KeymasterThank you Nickolas
The family of exitFullscreen commands indeed must be called directly on document, which is why attempting to call it on documentElement won’t work
Jeremy
Jeremy
KeymasterHi Irene,
It’s hard to tell what’s happening without the full context. If you don’t mind, it would be easier if you could send me the link to your experiment. One explanation could be that the MediaRecorder element is no longer active when the stop command on it tries to run, making the script crash before it can reach SendResults. Also, just to clarify, this early-exit bit of code is inside the Template command, right?
Re. the undefined trial getting stuck, do your sendrecords trials work as expected? That is, do they effectively upload the recordings?
Jeremy
Jeremy
KeymasterHey Nickolas,
I haven’t gotten around to implementing it yet, but I will add this to the next release. In the meantime, here’s a hack:
_AddStandardCommands( function(PennEngine) { this.actions = { pause: function (resolve){ if (this.type=="Timer" && this.running) { this.running = false; this.pausedTimestamp = Date.now(); this.events.push(["Pause","Pause",this.pausedTimestamp,"NULL"]); } resolve(); } , resume: function(resolve){ if (this.type=="Timer" && !this.running && this.pausedTimestamp) { this.resumedTimestamp = Date.now(); const offset = this.resumedTimestamp-this.pausedTimestamp; const newStartTime = this.startTime + offset; this.events.push(["Resume","Resume",this.resumedTimestamp,"NULL"]); this.start(); this.startTime = newStartTime; } resolve(); } } })
This technically adds the pause and resume commands to all PennController elements (that is, those that don’t already have them) but will take effect only with Timer elements. I haven’t tested that things get logged properly though, but be my guest.
Jeremy
Jeremy
KeymasterHi Nickolas,
I haven’t added an option to customize this message yet, so you’ll have to use the hack from this message
const replacePreloadingMessage = ()=>{ const preloadingMessage = $(".PennController-PennController > div"); if (preloadingMessage.length > 0 && preloadingMessage[0].innerHTML.match(/^<p>Please wait while the resources are preloading/)) preloadingMessage.html("<p>Loading, please wait</p>"); window.requestAnimationFrame( replacePreloadingMessage ); }; window.requestAnimationFrame( replacePreloadingMessage );
Jeremy
July 6, 2020 at 11:09 am in reply to: Redirecting from Qualtrics to PCIbex and then back to SONA #5752Jeremy
KeymasterHi Sam,
The get* commands represent PennController elements: as such, they can be parameters of other PennController commands, but you cannot simply use them in a plain string like this. What you can do is use the set command of the Var element, which lets you manipulate its value in plain javascript:
newTrial("genID", newVar("subjID") .global() .set(Math.floor((Math.random() * 10000) + 1)) ) .log( "id" , getVar("subjID")) newTrial( "testLink" , newVar("link") .set( getVar("subjID") ) // Fetch ID first, then insert it into the link .set( v => "<p><a href='https://umdsurvey.umd.edu/jfe/form/SV_a9pG7czZy4cfAPP?ID="+v+"'>Click here to go the next part of my study</a></p>." ) , newText() .text( getVar("link") ) .print() , newButton("Continue") .print() .wait() )
Jeremy
Jeremy
KeymasterHi,
This is a recurring question. You can upload a file named global_z.css and insert this content:
body { background-color: lightgray; }
Jeremy
July 1, 2020 at 6:57 pm in reply to: Making visuals (more) consistent across different display resolutions #5747Jeremy
KeymasterHi Nickolas,
You are correct in assuming that the units vw and vh are proportional to the page’s width and height (respectively). The command center on the other hand simply applies the CSS rule text-align: center; to the parent’s element, which (usually) occupies 100% of its own parent’s width.
Another thing that you should keep in mind is that unless you specifically set your font size to be proportional to your page’s dimensions, you will necessarily end up with different renderings depending on the page’s size. Also, most if not all browsers allow their user to set limits on font sizes, or to simply disable CSS styles (though people rarely do that).
One thing that is highly unpredictable is something like this:
newText("This is a very very very very very very very very very very very very very very very very long text.") .css("font-size", "4em") .print() , newButton("Click me") .size(100,50) .print("center at 50vw", "middle at 50vh")
Because your text is very long and its font size is quite big, chances are that small-resolution pages will wrap it and use multiple lines, so that it will end up overflowing the vertical center of the page, where the button is displayed (minus 50/2=25px). Besides, the print command simply appends the element below the other elements already on the page, including the progress bar.
In the case I give as an example, one solution would be this:
newText("This is a very very very very very very very very very very very very very very very very long text.") .print() .cssContainer({ "overflow-y": "scroll", "width": "100vw", "height": "calc(50vh - 25px - 60px)", // 60px = estimate of progress bar height "min-height": "unset" }) .css("font-size", "3vw") // Proportional to page's width , newButton("Click me") .size(100,50) .print("center at 50vw", "middle at 50vh")
It’s not perfect, but at least it’s responsive. Another option would be to print every element using coordinates, so you know exactly where they will be displayed on the page, and use size accordingly. But at the end of the day, there’s no magic recipe to have a universal rendering, every efficient web design necessitates a good amount of work, sometimes with quite sophisticated CSS rules (e.g. using the @media rule)
Jeremy
Jeremy
KeymasterHi,
The CheckPreloaded command, as its name indicates, creates a trial that only checks that the resources have been preloaded by the time it’s running, and if they haven’t it waits before proceeding to the next trial.
I was unaware of this problem, and I don’t see an immediate solution to it. The only thing I noticed is that it happens to me when I use Chromium, but not when I use Firefox.
I will need to proceed to some tests before I can identify the problem, I’m sorry
Jeremy
July 1, 2020 at 12:20 pm in reply to: Redirecting from Qualtrics to PCIbex and then back to SONA #5742Jeremy
KeymasterHi Max,
Follow the instructions on this page but at step 3, from the screenshot, replace
YOURSCHOOL.sona-systems.com/webstudy_credit.aspx?experiment_id=XXX&credit_token=YYY&survey_code=${e://Field/id}
with
expt.pcibex.net/ibexexps/[MYNAME]/[MYEXPERIMENT]/experiment.html?survey_code=${e://Field/id}Then, simply edit you last trial so it looks like this:
newTrial("endexp", newText("Your results have been saved, but you need to validate your participation below. This is a necessary step to grant you credits!").print(), newText("<a href='https://YOURSCHOOL.sona-systems.com/webstudy_credit.aspx?experiment_id=XXX&credit_token=YYY&survey_code="+GetURLParameter("survey_code")+"'>Click here to confirm my submission on SONA</a>.").print(), newButton("void").wait() )
You should probably also edit your header like this:
Header( // void ) .log( "ParticipantID" , GetURLParameter("survey_code") )
Let me know if this works
Jeremy
-
AuthorPosts