JavaScript & Qualtrics: Best Practices

Matt Bloomfield
8 min readOct 24, 2017

--

I’ve worked at Qualtrics for several years. It’s a wonderful platform for surveys, forms, questionnaires, etc. But its use can also be expanded almost infinitely by JavaScript. It’s not always been the most stable platform for JavaScript development, but with the recent transition to a JavaScript Form Engine (JFE) to power the surveys, things work better now than ever. In this post, I aim to highlight some best practices as well as some tips and tricks that people who are currently adding JavaScript to Qualtrics Surveys may or may not be aware of.

JFE vs SurveyEngine

While this is becoming more of a legacy issue, it’s important to remember that Qualtrics uses two different engines to power their surveys. SurveyEngine is the legacy platform that is largely deprecated at this point in favor of the JavaScript Form Engine. JFE, as it’s referred to, is a Single Page Application, dramatically decreasing page load times between pages but loading with a larger overhead cost initially. This is important because you need to keep in mind when writing JS that the head and window are not changing from page to page when the survey is running on JFE.

You can know if a survey is loaded using the new standard engine by looking at the URL. It will either have an /SE/ or /jfe/ in the center.

Best Practices for Great Results

Qualtrics is a really solid platform for JavaScript development and it can greatly extend the functionality already present in the platform. The following best practices are what I’ve found to keep things running smoothly.

Keep Code Where it Belongs

A place for everything and everything in its place. This is pretty simple, but JavaScript gets stripped from the HTML view of questions, so keep it in the JS editor for the question instead. CSS can be wrapped in <style> tags but you’re sure to lose it. Instead, keep it in the Custom CSS section of the look and feel.

Leverage the Qualtrics JS API

The Qualtrics JavaScript API is quite robust and gives you access to all kinds of functions, events, listeners, etc. that make integration with the platform easier. While there are some major gaps, the existing functionality is quite helpful.

One of the most useful methods is the this.questionClick(), because it allows you to get the value of the selected options. You can see its use here in a question type I created for an internal survey:

If you’re interested in using this question, add:

<span class=”selected-choice-text”></span><span class=”carrot”></span>

to the end of your question text while in HTML mode. Then add this to your Custom CSS in Look and Feel > Advanced > Custom CSS:

.carrot {
display:inline-block;
width: 30px;
height:30px;
background-image: url('https://survey.co1.qualtrics.com/ControlPanel/Graphic.php?IM=IM_e8m8EBRgg9W3pEp');
background-size: contain;
background-repeat: no-repeat;
background-position: center center;
float:right;
transform: rotate(90deg);
transition: transform .5s;
}
.carrot-closed {
transform: rotate(0deg);
}
.selected-choice-text {
margin-left: 5em;
color: #aaa;
font-style:italic;
}

Use jQuery when possible

jQuery is a common library used for JavaScript development. It handles errors very well, is compatible across hundreds of browser versions, and makes a lot of things very easy for front end developers. Luckily for you, jQuery is also included in Qualtrics for free, but probably not how you expect. While typical jQuery references use a $, Qualtrics has reserved that key for other things and instead uses jQuery as the selector. Rather than:

$('#QID4 input').click(function() {
analyzeInput($('#QID4 input').val());
});

You would instead write:

jQuery('#QID4 input').click(function() {
analyzeInput(jQuery('#QID4 input').val());
});

It’s not too different, basically just a Find and Replace on $ for jQuery.

Creating global functions in the header

The JavaScript functions you put in the Question JS blocks is only accessible from that scope. If you want to declare global functions, objects, variables, etc. you should use the Custom Header section of the Look and Feel. Just wrap your code in script tags and voila!

It would be good to keep your functions in some type of Object when pursuing this route. Something like this would do the trick:

Passing variables via Query String

When developing in JavaScript don’t forget about all the great resources it provides you with. Rather than developing independently of them, use them to your advantage. One way is to take advantage of the Embedded Data storage that Qualtrics uses by default. When running on JFE the following functions allow you to work with this easily:

Qualtrics.SurveyEngine.getEmbeddedData('<ED_KEY>');
Qualtrics.SurveyEngine.setEmbeddedData('<ED_KEY>');

Remember to declare your embedded data variable names in the Survey Flow if you want to access them using piped text or in your survey results. You can also pass variables into a survey using embedded data and query strings. For example, we use surveys as a ticketing system internally. We load the survey in an iFrame on our internal sites and pass employee id, name, and other metadata via query strings. We can then use that in the survey or pass it on to the final ticket upon survey complete.

Loading in libraries as files

Want to use a JavaScript library from someone else? Grab the minified .js file and add it to your Files Library in your Qualtrics account. Now grab that URL and add it as a <script src="<URL>"></script> in your header (Look and Feel > Advanced > Header). It’s now on the page for you to use! jscolor is an easy example resource to load in to change text input boxes to color selectors.

AJAX requests

While AJAX requests can be run straight from the JavaScript, don’t forget to take advantage of the newly renovated Web Service element in the Survey Flow. It now allows for POST, GET, UPDATE, PATCH, and DELETE requests, even supporting nested JSON bodies.

General Examples

I thought I’d throw in a few examples of things I’ve done recently that have been really helpful when developing in Qualtrics.

Stripe Integration

More and more people are wanting to use Qualtrics as a payment solution. The Stripe API makes it easy to integrate a payment modal into your page, and this solution records the payment token into Qualtrics so you can ensure you get paid before submitting the survey.

This saves two embedded data fields, PaymentToken and PaymentEmail that you can use to force them to pay using branch logic in the survey flow. Essentially, put this JS in the Question JS of a single question in a block, then force them to continually see that block until PaymentToken is not empty.

At this point, you are ready to charge the users. The key here is taking that saved token and sending it to Stripe as a POST request. This can luckily be done via the Qualtrics Web Service Element in the Survey Flow. This is lucky because it contains your secret key, which you wouldn’t want to expose publicly. The Web Service element runs server-side so people can’t Inspect Element and steal your token. Here is an example of what it should look like:

I recommend that, after getting a test Token from the first step, you come to this screen and run the request manually using the Test URL function. Stripe returns a ton of data about the transaction that you should store as Embedded Data. Once you’re ready to go, don’t forget to change out the Auth token for your Live key instead of the Test key.

And then boom! You’re set to go. It’s not one click, but in reality it’s pretty easy to add Stripe to a Qualtrics survey.

Toggled Stylesheets

Sometimes you want CSS to only appear on one page. While you could do this by simply adding it in nested <style> tags on that page, I wanted a programmatic way to do it.

First, I added the commented out CSS to the header in a style tag with an ID:

<style id="HideMyId">/*INACTIVE CSS#MyID {
display: none !important;
}
*/</style>

Then, I dropped the following function in the header:

pageService.toggleStylesheet = function(activate, id) {
if (!document.getElementById(id)) {return false;}
if (activate) {
document.getElementById(id).innerHTML = document.getElementById(id).innerHTML.replace( '/*INACTIVE CSS', '/*ACTIVE CSS*/');
} else {
document.getElementById(id).innerHTML = document.getElementById(id).innerHTML.replace( '/*ACTIVE CSS*/', '/*INACTIVE CSS');
}
};

As you can see, it just adds/removes the closing */ from the first comment, which coincidentally comments or uncomments the whole block.

Lazy Loaded CSS

You can always add resources to the header, but sometimes you don’t need them till a certain page. In my case, I wanted to be able to add a Google Font at will to a page. The following function set made this easy:

Change Background Image

This is pretty simple but useful for times when you only want the background image to occasionally show or to change mid survey.

Of course, this is easier accomplished via CSS if you do not need to modify this mid survey:

#SurveyEngineBody {
background: url("<myUrl>") no-repeat center center;
background-size: cover;
}

Downsides

While developing in JavaScript is great overall, there are a few downsides.

Lack of Code Highlighting and Version Control

The header can store virtually infinite amounts of information, but there is no code highlighting, it doesn’t save your tabs/spacing, and of course, there is no real version control.

Also, the JS editor is nothing compared to an IDE or text editor, so I usually do all my editing in Sublime Text 3 and then drop the changes into Qualtrics when I’m finished with them.

Slow Updates

Updates to the live links can be slow. The Preview link is usually updated close to live, but the Anonymous link can take up to 5 or 6 minutes to show changes. To help me out I usually create a console.log that logs out a version number. I then increment that version each time I make changes. Not ideal, but at least I know I’m testing the right code.

Incompatible Features

Unfortunately, there are some features that just don’t behave well with JavaScript. The main one is definitely page transitions. The problem is that Qualtrics is replicating the DOM while the transition is running, so you never know which DOM you are selecting. My recommendation? Just turn them off.

Conclusion

There is a lot to love about writing code in Qualtrics. I end up adding custom JS to almost every survey I write to enhance the experience. It’s a stable, reliable platform, and it allows for every function except document.write. While it has a few downsides, the best practices here should help you also get the very most from your Qualtrics JavaScript programming.

If you’re ready to move on — consider this guide to fixing the Modern Theme in Qualtrics. The step-by-step walkthrough is designed to help you think through the logic before making changes, but of course, there’s a fair amount of code as well!

--

--

Matt Bloomfield

Operations Specialist, Process Thinker, Tinkerer, Off Road Enthusiast, Husband, Father, Follower of Christ