Qualtrics has a JavaScript guide on their site for using their API. I think it’s terrible. This is my attempt at making a useful guide for JavaScript in Qualtrics.
Currently (5/11/21) Qualtrics can only read and write to variables already declared in the embedded data.
Qualtrics.SurveyEngine.setEmbeddedData("my_var", 7); // set my_var to 7
Qualtrics recommends reading via their standard jQuery method ${}. This useful for single variables, but does not scale too well with variables etc.
let my_var = "${e://Field/my_var}" // what Qualtrics recommend
let my_var = Qualtrics.SurveyEngine.getEmbeddedData("my_var") // what I recommend
For example I had a question where I wanted to had 20 questions and I randomly wanted to give hints for a certain amount of the Qualtrics. I was able to do this in a scalable way by reading in the correct answers, q\*_ans_letter, show them selectively based on another varaible in my embedded data q\*_show.
I was able to read
// population the buttons
var i;
var pre_answer = "The correct answer is: ";
var no_answer = "No help available";
for (i = 1; i <= 20; i++) {
let ans_q = "q" + i + "_ans_letter" // make embedded variable name
let show_q = "q" + i + "_show" // make embedded variable name
var ans = Qualtrics.SurveyEngine.getEmbeddedData(ans_q) // read in answer
var show = parseInt(Qualtrics.SurveyEngine.getEmbeddedData(show_q)); // show?
// write my answers to embedded variables accordingly
if (show == 1){
Qualtrics.SurveyEngine.setEmbeddedData("q" + i + "_text", pre_answer + " " + ans);
} else if (show == 0){
Qualtrics.SurveyEngine.setEmbeddedData("q" + i + "_text", no_answer);
}
}
I find it pretty useful to write answers to embedded data so that I can pipe them into a question on the next page.
Qualtrics.SurveyEngine.addOnPageSubmit(function() {
let selectedRecode = this.getChoiceRecodeValue(this.getSelectedChoices());
Qualtrics.SurveyEngine.setEmbeddedData("ans", selectedRecode);
});
Qualtrics.SurveyEngine.addOnPageSubmit(function() {
let slider_value =jQuery("#"+this.questionId+" .ResultsInput:eq(0)").val()
Qualtrics.SurveyEngine.setEmbeddedData("ans", slider_value);
});
Qualtrics.SurveyEngine.addOnPageSubmit(function(type)
{
let qid = this.questionId;
let question = document.getElementById('QR~' + qid);
let input = question.value;
// Qualtrics.SurveyEngine.setEmbeddedData("my_ans", input);
});
Qualtrics has a few
jQuery("input[type = hidden]").change(function() {
let answer = parseInt(jQuery("#" + currentQID + " input.ResultsInput").eq(0).val());
console.log(answer)
current.html("I am <b>" + answer + "%</b> certain that the best estimate, given what \
I’ve been told, is <b>" + bold_text + "</b>.");
var answer_temp = answer
var id ="${e://Field/question}";
id = parseInt(id);
Qualtrics.SurveyEngine.setEmbeddedData("answer_"+id, answer_temp);
});
HTML <div id="current" style="text-align: center;"><span style="color:#ffffff;">.</span></div>
Qualtrics doesn’t have a built in way to evenly randomize loop and merge. Here’s a hack on how to do it.
In a question before on a block before the loop and merge
Qualtrics.SurveyEngine.addOnload(function()
{
var questionDiv = this.getQuestionContainer(); // get question
questionDiv.style.display = "none"; // hide question
this.clickNextButton(); // automatically advance
});
https://web.archive.org/web/20190606134631/https://voices.uchicago.edu/kariyushi/qualtricstimeoff/
Most of the Qualtrics JS we see is within question, but often it is useful to have one main question on a page that allows me to set the JS. I especially use this pattern in Loop & Merges with a lot of conditional questions.
let currentQID = this.questionId // we usually see this
let Q2QID = Object.keys(Qualtrics.SurveyEngine.QuestionInfo)[1] // use the second question
https://www.qualtrics.com/community/discussion/7570/how-can-i-count-errors
var question = $(this.questionId)
$(question).select('.ValidationError').each(function(error) {
if (error.innerHTML != '') {
var errors = parseInt(Qualtrics.SurveyEngine.getEmbeddedData("errors_q_1"))
errors++;
Qualtrics.SurveyEngine.setEmbeddedData("errors_q_1", errors);
}
})
Qualtrics.SurveyEngine.addOnReady(function(){
var n=jQuery("#"+this.questionId+" .ChoiceRow").length;
if(jQuery("#"+this.questionId+" .ValidationError").text()!=""){
for(var i=0;i<n;i++){
if(jQuery("#"+this.questionId+" .ChoiceRow:eq("+i+") td input[type='radio']:checked").length==0){
jQuery("#"+this.questionId+" .ChoiceRow:eq("+i+")").css("background","lightpink");
}
}
}
});
// randomly assign list1:list4 w/o replacement
var bucket = ["cc", "cs", "sc", "ss"]; // set conditions
function getRandomFromBucket() { // define function
var randomIndex = Math.floor(Math.random()*bucket.length);
return bucket.splice(randomIndex, 1)[0];
}
// use function four times to assign all
Qualtrics.SurveyEngine.setEmbeddedData("list1", getRandomFromBucket());
Qualtrics.SurveyEngine.setEmbeddedData("list2", getRandomFromBucket());
Qualtrics.SurveyEngine.setEmbeddedData("list3", getRandomFromBucket());
Qualtrics.SurveyEngine.setEmbeddedData("list4", getRandomFromBucket());
A switch statement can take an input and conditionally assign variables. Here’s a case where I loop inputs into a switch statement to assign conditional embedded variables
// set embedded data conditional on list
for (var i=1;i<=4;i++) {
current_list = Qualtrics.SurveyEngine.getEmbeddedData("list"+i);
switch (current_list) {
case "cc":
left = "Donation for GiveDirectly"
right ="Donation for GiveDirectly"
prefix = "cc"
break;
case "cs":
left ="Donation for GiveDirectly"
right ="Bonus for You"
prefix = "cs"
break;
case "sc":
left ="Bonus for You"
right = "Donation for GiveDirectly"
prefix = "sc"
break;
case "ss":
left ="Bonus for You"
right ="Bonus for You"
prefix = "Bonus for You"
break;
default:
break;
}
Qualtrics.SurveyEngine.setEmbeddedData("prefix"+i, prefix);
Qualtrics.SurveyEngine.setEmbeddedData("left"+i, left);
Qualtrics.SurveyEngine.setEmbeddedData("right"+i, right);
}
Suppose you ask the same demographic on every survey. You could imagine importing all of the questions at once. This is the correct thing to do in most cases. The questions will remain static, and for posterity you’ll be always be able to reference as it was. But suppose you were running multiple congruent surveys and wanted to make changes to them all globally? In this case, it could make sense to instead reference the Demographic survey.
Countless StackOverflow users, Qualtrics community members, but especially TomG.