Jeremy

Forum Replies Created

Viewing 15 posts - 1,186 through 1,200 (of 1,522 total)
  • Author
    Posts
  • in reply to: Not sending results #5776
    Jeremy
    Keymaster

    Hi 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,
    Jeremy

    in reply to: Uploading Recordings on a Virtual Machine #5771
    Jeremy
    Keymaster

    Hi 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

    in reply to: Restricting to desktop #5770
    Jeremy
    Keymaster

    Hi,

    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

    in reply to: Password reset #5769
    Jeremy
    Keymaster

    Hello 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

    in reply to: Not sending results #5765
    Jeremy
    Keymaster

    I’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

    in reply to: Safari Compatibility #5760
    Jeremy
    Keymaster

    Thank 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

    in reply to: Not sending results #5759
    Jeremy
    Keymaster

    Hi 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

    in reply to: Exit button #5756
    Jeremy
    Keymaster

    Hey 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

    in reply to: Catch Trials #5754
    Jeremy
    Keymaster

    Hi 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

    Jeremy
    Keymaster

    Hi 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

    in reply to: background color #5751
    Jeremy
    Keymaster

    Hi,

    This is a recurring question. You can upload a file named global_z.css and insert this content:

    body {
      background-color: lightgray;
    }

    Jeremy

    Jeremy
    Keymaster

    Hi 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

    in reply to: Preloading at a specific point in the trial sequence #5746
    Jeremy
    Keymaster

    Hi,

    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

    Jeremy
    Keymaster

    Hi 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

    in reply to: Including InitiateRecording in Sequence #5740
    Jeremy
    Keymaster

    Hi,

    You can use label, like this:

    Sequence( "intro" , "init" , sepWith("sep", randomize("test")) )
    
    InitiateRecorder("https://url.to/file.php/")
      .label( "init" )

    Jeremy

Viewing 15 posts - 1,186 through 1,200 (of 1,522 total)