I've been given some javascript code for recording keyboard presses in Qualtrics. Seems to work fine when I preview the survey, but as soon as I use the distribute survey link, it does not work at all.
I'm using this code for before the event I want to record 'x' keyboard presses for:
Qualtrics.SurveyEngine.addOnload(function()
{
Event.observe(document, 'keydown', function (e) {
switch (e.keyCode) {
case 88: // 'x' was pressed
var totalpresses = Qualtrics.SurveyEngine.getEmbeddedData("xhits");
if (totalpresses == "NaN"){totalpresses=1;}
totalpresses = parseInt(totalpresses);
totalpresses = totalpresses + 1;
Qualtrics.SurveyEngine.setEmbeddedData("xhits",totalpresses);
}
});
});
and i'm using this code for following the event:
Qualtrics.SurveyEngine.addOnload(function()
{
var totalpresses = Qualtrics.SurveyEngine.getEmbeddedData("xhits");
Qualtrics.SurveyEngine.setEmbeddedData("finalxhits", totalpresses);
which gives me 'xhits' for the section I need it for, but only when I preview the survey.
I am using embedded data in the survey flow to create 'xhits' and 'finalxhits', yet finalxhits doesn't seem to show a value either (not that this is the problem).
I am very new to javascript so would appreciate any help.
I'm not sure what is causing your issue (I haven't tried to recreate it), but try this:
Qualtrics.SurveyEngine.addOnload(function()
{
var totalpresses = parseInt("${e://Field/xhits}");
if (isNaN(totalpresses)) totalpresses = 0;
Event.observe(document, 'keydown', function (e) {
switch (e.keyCode) {
case 88: // 'x' was pressed
totalpresses = totalpresses + 1;
Qualtrics.SurveyEngine.setEmbeddedData("xhits",totalpresses);
}
});
});
Is that second piece of code attached to a subsequent question? I'm not sure what purpose it serves, but you can just do that assignment in the survey flow:
finalxhits = ${e://Field/xhits}
Related
I've tried several javascript functions here and there but it seems that none of them worked for me.
What I'm doing is displaying a tower, that has as many stages as the user wishes. This is basically creating HTML tags using Js for every stage and the last one is a checkbox.
The thing I'd like to do is that when I click on a checkbox, all the other ones that are over this one would check programmatically also. So this is what I did:
let event = new Event('click');
//Here, q is the maximum stage that the user set.
document.addEventListener('click', function(e) {
let readStr = e.target.id;
if (readStr.startsWith("checkboxFan") && e.isTrusted) {
for (let r=parseFloat(readStr.substr(-1))+1; r<=q; r++) {
document.getElementById("checkboxFan"+r).dispatchEvent(event);
}
}
}, false);
And it's finding the IDs well and doing what I want, but the dispatchEvent isn't working as expected. In fact, it's not working at all. Also, the "click()" function works but the isTrusted is triggered, which is not what I want because the checkbox has to be clicked by the user.
Any solutions?
I've written some code based on your description.
https://stackblitz.com/edit/js-poevax?file=index.js
document.addEventListener(
"click",
function(e) {
let readStr = e.target.id;
if (readStr.startsWith("checkboxFan") && e.target.checked) {
for (let r = parseFloat(readStr.substr(-1)) + 1; r <= q; r++) {
document.getElementById("checkboxFan" + r).checked = true;
}
}
},
false
);
You should check this page.
Input Checkbox checked Property
cheers!
I'm a newbie to coding, and this topic is probably very common, but it has me pretty confused.
I have a button:
<button onclick = typeWriter()>/click</button>`
My function:
var myArray = ['such', 'something else', ];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
var i = 0;
var speed = 55;
function typeWriter() {
if (i < rand.length) {
document.getElementById("question").innerHTML += rand.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
}
How do I add a keyboard key like the spacebar as an event listener or something similar, so that when I press the spacebar (and not in a text box), it presses the button and triggers the function? A simple vanilla javascript answer would be preferable, since I don't get jQuery.
Would it be better to simply add script that triggers myFunction with the spacebar rather than going through triggering the button? And if so, how do I program that?
BTW: I'm trying to do this for mobile, using an iPad keyboard. Will that change anything?
Thanks.
You can add a listener on window if you want to trigger your function everywhere of your html.
window.onkeydown = function(event) {
if (event.keyCode == 32) {
//your function here
};
};
Here you can find all key codes for keyboard: https://keycode.info/
don't use inline JS
Use addEventListener()
Use Event.key to determine the pressed key
Use a helper function to determine if the current Event.target is a FormElement
// Function to detect if el is a form element
const isFormElement = el => /^(input|textarea|select|button)$/i.test(el.nodeName);
// Example function
const myFunction = ev => console.log("HELLO!");
// Find buttons in DOM
const EL_myfn = document.querySelectorAll('.js-myFunction');
// Trigger directly on buttons click
EL_myfn.forEach(el=> el.addEventListener('click', myFunction));
// And on keydown
window.addEventListener('keydown', ev => {
// If spacebar is hit, and we're not inside a forminput element
if (ev.key === " " && !isFormElement(ev.target)) {
myFunction();
}
})
textarea{width: 100%;}
<button class="js-myFunction">Click me! (Console should log)</button>
<div>press spacebar here (Console should log)</div>
<textarea>press spacebar here (Console should not log!!)</textarea>
I'm very new to JavaScript, and I'm currently trying to add a custom code to my Qualtrics survey that makes it so pressing the spacebar continues the survey in the "Text/Graphic" question type. I have a code that should be working; however, I'm getting an "Unexpected token (" error.
Here is the code:
Qualtrics.SurveyEngine.addOnload(function()
{
document.addEventListener("keydown", function(e) {
if (e.keyCode === 32) {
function(){
that.clickNextButton();
}
}
}
});`
I also found this answer to a similar question from a couple of years back:
Here is a simplified version that works (updated to hide NextButton):
Qualtrics.SurveyEngine.addOnload(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 13) $('NextButton').click();
});
});
This code, however, doesn't work at all in my survey (as if it wasn't even there).
Any help is much appreciated, thanks in advance!
____ Edit _____
The code I have now used is the following:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
});
Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 32) $('NextButton').click();
});
});
});
Qualtrics.SurveyEngine.addOnUnload(function()
{
/*Place your JavaScript here to run when the page is unloaded*/
});
The problem I have now is that the study autoadvances the next question whenever I press spacebar before ansewring a previous question.
Example
Question 1: Is the sentence you just saw a sensible continuation for the preceding sentence?
* participant presses space bar before answering the question with F for no and J for yes
* The study reminds the participant that they need to answer the question before proceeding to the next question
* Participant answers the question and the study automatically proceeds to the next question, because answering validates the question
--> the study only lets the participant see the next item for a second, and then autoadvances to the next item without the participant pressing any key.
The code I use for the F + J keys is the following:
Qualtrics.SurveyEngine.addOnload(function()
{
this.hideNextButton();
this.hidePreviousButton();
var that = this;
Event.observe(document, 'keydown', function keydownCallback(e) {
var choiceID = null;
switch (e.keyCode) {
case 74: // 'f' was pressed
choiceID = 2;
break;
case 70: // 'j' was pressed
choiceID = 1;
break;
}
if (choiceID) {
Event.stopObserving(document, 'keydown', keydownCallback);
that.setChoiceValue(choiceID, true);
that.clickNextButton();
}
});
});
I think it doesn't work due to a timing issue. Use addOnReady instead:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
document.on("keydown", function(e) {
if (e.keyCode === 32) $('NextButton').click();
});
});
Note: with split screen preview mode you have to click in the window first or it won't recognize the key press.
EDIT:
I couldn't recreate your problem (your code worked as is for me when I tried it). However, try the following. It is cleaner and consistent. If it works be sure to accept the answer.
Space bar question:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
if($('PreviousButton')) $('PreviousButton').hide();
var evt = document.on('keydown', function(e) {
if (e.which == 32) { //space bar pressed
evt.stop();
$('NextButton').click();
}
});
});
Yes/No question:
Qualtrics.SurveyEngine.addOnReady(function() {
$('NextButton').hide();
if($('PreviousButton')) $('PreviousButton').hide();
var that = this;
var evt = document.on('keydown', function(e) {
var choiceID = null;
if(e.which == 70) choiceID = 1; //'f' was pressed
else if(e.which == 74) choiceID = 2; //'j' was pressed
if (choiceID) {
evt.stop();
that.setChoiceValue(choiceID, true);
$('NextButton').click();
}
});
});
You need to remove the function() around that.clicknextbutton(), and change that to this. that doesn't make sense unless it is a variable set to the this keyword. The function(){} syntax is used to define an expression in a parameter.
Qualtrics.SurveyEngine.addOnload(function(){
document.addEventListener("keydown", function(e) {
if (e.keyCode === 32) {
this.clickNextButton();
}
});
});
I am currently developing a javascript game, and I can't get touch controls to work on mobile devices. It is a simple game, in which you can press Up arrow to jump, or Down arrow to roll.
I would like to also implement the touch controls, so the touch/hold of the left side of the display would make the character roll, and by touching/holding the right side of the screen, the character jumps.
This is the code that is working for me for the Up and Down arrow:
var KEY_CODES = {
38: 'up',
40: 'down'
};
var KEY_STATUS = {};
for (var code in KEY_CODES) {
if (KEY_CODES.hasOwnProperty(code)) {
KEY_STATUS[KEY_CODES[code]] = false;
}
}
document.onkeydown = function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = true;
}
};
document.onkeyup = function(e) {
var keyCode = (e.keyCode) ? e.keyCode : e.charCode;
if (KEY_CODES[keyCode]) {
e.preventDefault();
KEY_STATUS[KEY_CODES[keyCode]] = false;
}
};
And then I can make tha character to do things by doing:
if (KEY_STATUS.up) { stuff and things }
Any advices, hints, recommendations or possible code scraps that might help me? Thanks in advance!
You should be able to use touch events. In many cases you can use the same functions that you wrote for the keypresses, or you can write them separately. Here's an example
var touchedElement = document.getElementById("myElementToBeTouched");
touchedElement.addEventListener("touchstart", funcTouchStart, false);
touchedElement.addEventListener("touchend", funcTouchEnd, false);
touchedElement.addEventListener("touchmove", funcTouchMove, false);
function funcTouchStart(e) {
//code to do what you want like set variables and check where on screen touch happened
var touches = e.changedTouches; //gets array of touch points, to get position
}
function funcTouchEnd(e) {
//code
}
function funcTouchMove(e) {
//code
}
To make them respond to left or right screen, you could use the touches[i].pageX that comes with these events and set the action to happen only if in the 25% of the screen from touches[i].pageX = 0 (for left) or last 25% to where the touches[i].pageX = width of screen/viewport.
This is not a complete working example but I hope its enough to give you an idea of what you could do. If you need more help with these events, try looking at one of MDN examples such as:
https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Touch_events
I can't believe this hasn't been asked before (I searched and searched) but anyway.
How can I switch key events with pure JS?
For example, I want to switch the Enter button to mimic the Tab button. (I want to be able to push enter without submitting the form and instead switch fields to a Tab-like behavior e.i. switch form fields)
var enter = 13;
if (e.which === enter) {
// tabs to next field
getNextField(e.srcElement).focus();
// stops default enter
event.preventDefault();
event.stopPropagation();
}
implement getNextField() using .tabindex
function getNextField(obj) {
var next = obj.tabIndex + 1;
var all = document.getElementsByTagName("*");
for (var i in all) {
if (all[i].tabIndex === next) {
all[i].focus();
break;
}
}
}
This should give you a vague idea of how to do it. Flesh out the pseudocode yourself.