I am designing a survey, wherein every question is scored, and a final score is calculated on the basis of these individual scores using a mathematical formula (for now, consider a simple summation of all scores, which is then multiplied by 3). So I wanted help on two fronts:
1. Firstly, it seems I need to create an embedded data field to calculate the final score, but the formula I've typed isn't working. Need to figure out what's wrong in my current formula or if an easier one is possible
!
2. Secondly, I want to display this final score on the top of the page. When we change our response to a question (by selecting another option), this score should be immediately be updated without me going to a different page. I know it seems strange for a respondent to immediately know how his/her response changes the final score, but this is by deliberate design in this case. I tried using solutions to these questions, but wasn't able to make them work:
https://www.qualtrics.com/community/discussion/comment/41#Comment_41
https://www.qualtrics.com/community/discussion/3092/creating-a-variable-to-add-all-the-scores-of-the-survey-respondents
I am new to both JS and HTML as well and am learning it as I go along making this survey.
Would be really grateful if someone could help me out on this!
Thanks!
Next, use piped text to pipe in the embedded data "Final Score" wherever you'd like (though the header or footer would be the easiest).
> 1. Firstly, it seems I need to create an embedded data field to calculate the final score, but the formula I've typed isn't working. Need to figure out what's wrong in my current formula or if an easier one is possible
> !
You need to add spaces between all the fields and operators in your formula. For example:
```
$e{ ( q://QID1/SelectedChoicesRecode + q://QID2/SelectedChoicesRecode ...etc...
```
> 2. Secondly, I want to display this final score on the top of the page. When we change our response to a question (by selecting another option), this score should be immediately be updated without me going to a different page. I know it seems strange for a respondent to immediately know how his/her response changes the final score, but this is by deliberate design in this case. I tried using solutions to these questions, but wasn't able to make them work:
You'll need to do this in JavaScript. Pipe the answers you need to calculate the score into your JS. Add event listener(s) to recalculate and update the displayed score whenever the answer changes.
Sorry for the late response back, but at the time of asking the question I had little to no knowledge of HTML and Javascript, so spent some time understanding things on w3schools. I tried to implement the solution you suggested but am still confused on certain aspects of point
2. To be entirely clear, I’ll use an example below to convey my problem.
!
Suppose I have a survey with 7 questions (q1, q2, q3...) with a different number of options in each question (the options can be labelled as q1: {a11, a12, a13}, q2: {a21, a22, a23, a24, a25}, q3: {a31, a32, a33, a34} and so on. All questions are multiple-choice, single-answer. The score for the options can be x11, x12, x13, x21, x22… etc. (the numbers are all decimals): when I select a11, the score displayed on the page should be = x12. If after that, I select a22, the score should be = x11 + x22. If I deselect option 11, the score should automatically update to x22, without me needing to change the page. I may need to do more complex mathematical operations to make a final score from x11, x12, etc. but I guess that’s a problem to be tackled later.
I tried two things: either displaying the score in the first question (which I set as a descriptive text question for the purpose) or in the header. To begin with, I just wanted to try and display the score of one question, and see if it updates or not. For the same, I tried adding a span element with id = “final_score” in either of them. Then I add the following code to every question:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
this.questionclick = function(event, element){
var choiceNum = jQuery("#"+this.questionId+" input.radio:checked").attr("choiceid")
/* the number of keys and values change in every question. These numbers are representative*/
var recodeMap = {"1" : 0.7, "2" : 0.23, "3" : 1.89};
var qScore = recodeMap choiceNum];
}
document.getElementById("final_score").innerHTML = qscore
});
But the score doesn’t display in the survey. More over, I’m not sure how to add the scores across questions (or perform more complex mathematical operations on them). Then I tried setting an embedded data field (called Final_Score) and adding the scores of various questions to that. The code for that is as follows:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
var iScore = parseInt("${e://Field/Final_Score}", 10);
this.questionclick = function(event, element){
var choiceNum = jQuery("#"+this.questionId+" input.radio:checked").attr("choiceid")
var recodeMap = {"1" : 1, "2" : 1, "3" : 1, "4" : 1, "5" : 1, "6":1};
var qScore = recodeMaprchoiceNum];
var fScore = iScore + qScore;
Qualtrics.SurveyEngine.setEmbeddedData("Final_Score", fScore);
//alert("fScore is:" + fScore);
}
document.getElementById("final_score").innerHTML = "Total Score: " + fScore;
}
The problem that arose here was that the embedded data field only updates once I leave the page, so that didn’t work out either. The document.getElementById wasn’t working either.
As of now, I *think* as per your advice I have to add event listeners for all questions of my survey block (there are 7-8 in one block) in the JS of one beginning question or the header. Problem is I don’t know how to access the question objects. In the JS of a question, the methods and properties of the question object are easily accessible through the qualtrics API – this.questionclick etc., but I’m not sure how to access the values of another question object.
Apologies for the length, and I’d be really grateful if someone could give some hints with regards to where to go from here.
To simplify it, you should:
1. Have one MC question per page
2. Use Qualtrics Scoring to keep track of a total score. This way you only need worry about updating the score on the current page.
3. Make use of jQuery
So, on each page let's say you have a descriptive text question with the html (assuming SC_xyz is an actual scoring id from your survey):
```
Your current score is <span id="totalScore">${gr://SC_xyz/Score}</span>
```
Now, you'll need to update the contents of totalScore when the respondent selects a MC answer. So, JS for your MC question:
```
Qualtrics.SurveyEngine.addOnload(function() {
startScore = parseInt("${gr://SC_xyz/Score}");
choiceScores = {"1" : 5, "2" : 10, "3" : 20};
jQuery("#"+this.questionId+" input[type=radio]").click(function() {
var score = startScore + choiceScores[jQuery(this).attr("choiceid")];
jQuery("#totalScore").html(score);
});
});
```
Would there not be any way of having multiple questions on the same page? The final questionnaire might be much longer (~50 questions) and the respondent would often have the need to revisit some previous response.
In such a situation, I could see that to see the score the respondent would have to scroll to the very top, which would also be inconvenient. But possibly the inconvenience caused due to difficulty in accessing a particular question might be greater.
EDIT: I figured out how to keep the score fixed at the top (even if right now it looks a little ugly). In the first question, I added the following HTML
<div class = "question">
Total Score is: <span id="tScore">${gr://SC_0AllARgoJfrJDr7/Score}</span>
</div>
<div class = "question_spacer">
This is a spacer element
</div>
<style>
.question{
background: white;
width:100%;
z-index: 1000;
text-align:center;
}
.question.fixed{
position: fixed;
top:0;
left:0;
}
.question_spacer{
height: 20px;
visibility: hidden;
display:none;
}
.question_spacer.fixed{
display:block;
}
</style>
And added the following Javascript
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
$$('.question').forEach(ele=>ele.addClassName('fixed'));
});
So all I need to figure out is to how to update the score.
```
Qualtrics.SurveyEngine.addOnload(function() {
totalScore = jQuery("#totalScore");
choiceScores = {"1" : 5, "2" : 10, "3" : 20};
jQuery("#"+this.questionId+" input[type=radio]").click(function() {
var score = parseInt(totalScore.text()) + choiceScores[jQuery(this).attr("choiceid")];
jQuery("#totalScore").text(score);
});
});
```
Thanks! I did a little variation on this, and it worked! The coding I've done right now doesn't look pretty, but doesn't take too much time to run, and I can work on improving it later on.
Sorry for the long time to replies. This has been really helpful.
As for the solution, the thing that seemed to work best for me was to have a look at ALL question responses every time an option was changed (so that as I change responses, the score doesn't keep on getting incremented indefinitely), and update totalscore accordingly. Instead of adding JS to each question, I added one long code to the first question:
`Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
//$$('.question').forEach(ele=>ele.addClassName('fixed'));
/*Implements scoring on clicking of any of the radio buttons*/
jQuery("input[type=radio]").change(function() {
if(jQuery("#QID10 input.radio").is(":checked")){
var choiceNum1 = jQuery("#QID10 input.radio:checked").attr("choiceid");
var recodeMap1 = {"1" : 1, "2" : 1, "3" : 1, "4" : 1, "5" : 1};
var qScore1 = recodeMap1[choiceNum1];
} else {
var qScore1 = 0;
}
if(jQuery("#QID14 input.radio").is(":checked")){
var choiceNum2 = jQuery("#QID14 input.radio:checked").attr("choiceid");
var recodeMap2 = {"1" : 3, "2" : 1, "3" : 1, "4" : 3, "5" : 0, "6" : 1};
var qScore2 = recodeMap2[choiceNum2];
} else {
var qScore2 = 0;
}...
//This is pseudocode displaying sum of n scores
//qScore = qScore1 + qScore2 + ...qScore(n);
//Updating totalscore
jQuery("#totalscore").html(qScore);
});
});`
Obviously the code is quite inelegant and still has issues. Accessing scores of other questions in one means I have to manually enter their QIDs and since a lot of questions have been reordered/deleted, these QIDs don't follow a natural progression. Also I can imagine debugging being a bit of pain later on, but for a first stab I'm satisfied. Hopefully, I don't have to revisit this many times ! Now I move on to other pains.
Thanks once more!
Hello All,
Thank you for posting this code! I want to do something similar and have adpated it for the three questions I want to dynamically show "total scores" for. However, I'm not able to get the score itself to show up in the descriptive text. I don't know any JS at all... could someone please help me figure out how to print it? THANK YOU :)
This is the code I have in the descriptive question that comes before the three single-answer MC questions that appear on the page:
Your current score is ${e://Field/etotalscore}
And here is the JS code I added to the descriptive question:
Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/
jQuery("input[type=radio]").change(function() {
if(jQuery("#QID636 input.radio").is(":checked")){
var choiceNum1 = jQuery("#QID636 input.radio:checked").attr("choiceid");
var recodeMap1 = {"1" : 0, "2" : 100, "3" : 200, "4" : 300, "5" : 400, "6" : 500, "7" : 600, "8" :700, "9" : 800, "10" : 900, "11" : 1000};
var qScore1 = recodeMap1pchoiceNum1];
} else {
var qScore1 = 0;
}
if(jQuery("#QID653 input.radio").is(":checked")){
var choiceNum2 = jQuery("#QID653 input.radio:checked").attr("choiceid");
var recodeMap2 = {"1" : 10, "2" : 20, "3" : 30, "4" : 40, "5" : 50};
var qScore2 = recodeMap2 choiceNum2];
} else {
var qScore2 = 0;
}
if(jQuery("#QID644 input.radio").is(":checked")){
var choiceNum3 = jQuery("#QID644 input.radio:checked").attr("choiceid");
var recodeMap3 = {"1" : 0, "2" : 50, "3" : 100, "4" : 150, "5" : 200};
var qScore3 = recodeMap3qchoiceNum3];
} else {
var qScore3 = 0;
}
var qScore = qScore1 + qScore2 + qScore3
jQuery("#totalscore").html(qScore);
jQuery("#totalscore").text(qScore);
Qualtrics.SurveyEngine.setEmbeddedData("eJStotalscore",qScore);
});
});
avashist,
Your current score is ${e://Field/etotalscore}
I canot thank you enough, TomG! I have literally been banging my head against my desk for the entire week trying to get this to work :)
As a warning to others who might come after me, trying to do the same thing:
If you add and delete choices from the questions, the "underlying" values/tags of the options will not be 1, 2, 3, 4, etc... because I was "reusing" my MC questions in order to retain the formatting (copying the original question, deleting the previous question choices, and adding new ones for subsequent questions), my recode function was not working This was because the options from my MC had underlying values/ tags = 8, 34, 35, 36, 37, etc.
Thanks TomG for getting the number to show up, so I could figure this out!
Hello and thank you for your fantastic help on the topic so far.
I came across this post and despite very limited JS knowledge was able to use it in a test run.
However, for my purposes I need to allow multiple answers to each question. Meaning a respondent will e.g. have the option to choose between "apples", "bananas", "cherries" and "strawberries" as well as a "none" option.
The respondent can then choose to select only one option or multiple options (except for when "none" is chosen which I have set to exclude other answers) within each of the three questions.
Would it be possible to adjust the code used by @avashist for my purposes?
I would be grateful for any suggestions.
Thank you!
Leave a Reply
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.