PennController for IBEX › Forums › Support › Can we use template literals in Pcibex? › Reply To: Can we use template literals in Pcibex?
Hello,
If you haven’t done so already, I invite you to read <the Core Concepts section in addition to the guide your reference, which also contains some pointers about the proper syntax and scope of PennController commands
I’ll start with your second message. All PennController commands are javascript functions. When you do newTrial( /* ... */ )
whatever you write in place of /* ... */
are arguments to the function newTrial
. It is illegal in javascript to use the let
keyword to define a variable as part as an argument, so you cannot do things like newTrial( "myTrial", let time = 100 , newTimer("timeout", time) , /* ... */ )
. However, you can do things like newTrial( "myTrial", time = 100 , newTimer("timeout", time) , /* ... */ )
because omitting let
will make the expression time=100
return 100
, which is a valid argument to pass to a function. Note that this would not set time
as a local variable, as in “in the scope of newTrial
“, because you simply are not in its scope (you’re just passing arguments)
Now back to your first message. The files you upload to Resources are not just all thrown into the page when you open the experiment, otherwise it would be a real mess. What happens at the beginning of the experiment is your scripts get executed before body
even gets populated, so any reference like document.querySelector(".form__btn--submit");
that you put at the root of your script will simply return null
. However, Ibex with its Message and Form controllers, and PennController with newHtml
(or newController
+ Message/Form) allow you to dynamically inject HTML files from the project’s Resources folder at some point during your experiment. The HTML files you upload to Resources can include CSS and javascript. However, the references in <link rel="stylesheet" href="style.css" />
and <script defer src="script.js"></script>
will fail on the farm, because the project’s files are not simply exposed at the local path. So you might want to include CSS + javascript in the HTML document, as in:
<html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="description" content="..." /> <script> "use strict"; // embed code in an async function so as to wait for the button element to be added to the page const runScript = async () => { /// SELECT BUTTON: const btnSubmit = await new Promise(function getBtn(r) { const b = document.querySelector(".form__btn--submit"); if (b===null) window.requestAnimationFrame(()=>getBtn(r)); else r(b); }); // SELECT INPUT: const inputSubmitName = document.querySelector(".form__input--name"); const inputSubmitAge = document.querySelector(".form__input--age"); // SELECT BOX MESSAGE: let welcomeMsg = document.querySelector(".welcome"); // SELECT FORM DIV const formDiv = document.querySelector(".operation--welcome"); // SELECT AND MANIPULATE CONTENT: btnSubmit.addEventListener("click", function (e) { // Prevent default: e.preventDefault(); // Get name and age const name = inputSubmitName.value; const age = +inputSubmitAge.value; // transform string to a number // Make it disappear: formDiv.classList.add("welcome--hidden"); // Display Welcome User Message: welcomeMsg.classList.remove("welcome--hidden"); welcomeMsg.textContent = `Hello, ${name}! You are ${age} years old. Welcome! 🤗`; ////////////// HERE!! // log console.log(age, name); }); }; runScript(); </script> <style> /* general properties of document */ * { margin: 0; padding: 0; box-sizing: inherit; } body { font-family: "Poppins", sans-serif; font-weight: 300; color: yellow; /* cor do texto */ line-height: 1.9; background-color: #3616d9; /* cor do fundo */ } .form--title { position: absolute; left: 400px; height: 350px; width: 550px; bottom: 90px; } .form--personal__info { position: absolute; left: 300px; height: 350px; width: 550px; bottom: 50px; } .welcome-message { background-color: aquamarine; text-align: center; font-size: 30px; width: 100%; position: absolute; height: 80px; bottom: 280px; color: red; } .welcome--hidden { opacity: 0; transform: translate(20px, 20px); } </style> <title>My first form</title> </head> <body> <div class="operation operation--welcome"> <h2 class="form--title">Personal Info:</h2> <form class="form form--personal__info"> <input type="text" class="form__input form__input--name" placeholder="Your Name here"/> <input type="number" class="form__input form__input--age" placeholder="Your Age Here"/> <button class="form__btn form__btn--submit">→</button> <label class="form__label">Submit your data 👈</label> <!-- <label class="form__label">your data 👈</label> --> </form> </div> <div class = "welcome welcome-message welcome--hidden"> <h2 class="new--message">Welcome, user! 😀</h2> </div> </body> </html>
Note that the CSS rules will come after those already in place by Ibex + PennController, so you will want to adapt them (in particular, the position:absolute;
shifts your content outside the visible portion of the page)
Then you can do something like this:
newTrial( newHtml("my_file.html").print() , newButton("Next") .print() .wait() )
Jeremy