showing feedback with additional text after each question | XM Community
Question

showing feedback with additional text after each question

  • 28 December 2020
  • 23 replies
  • 281 views

Hello All,
I am relatively new to qualtrics and would like to know how to achieve the following.
I have enabled scoring on my survey page and after a respondent answers each question,
it shows them the original question with feedback (whether they selected the right answer or not).
On this feedback page, i want to add additional text on why a particular answer is right. However i m not sure the best way to do that.
It looks like on the scoring feedback page,
Qualtrics.SurveyEngine.addOnload() or the addOnReady is not called. So i am not able to show/hide the div text that i would like to display on that feedback page.
Is there another way to do this?
Thanks!


23 replies

Wanted to bump this up for any ideas? Thanks!

Userlevel 7
Badge +27

https://www.qualtrics.com/community/discussion/comment/32948#Comment_32948You probably haven't gotten any responses because your question isn't very clear. An image might help. Also, addOnload and addOnReady are always called. There is probably a problem with your JS. If you are asking for help with JS, you should post your code.

Userlevel 7
Badge +21

The functions are not called, because a new page is not being called. Just the dom is being modified. This JS will work for feedback that is displayed after the question.
Qualtrics.SurveyEngine.addOnReady(function () {
    document.querySelector("#NextButton").addEventListener("click", grading_text);
    qid = this.questionId;


    function grading_text(){
        var gt = setInterval(function (){
            if(document.getElementById(qid).className == "Grading"){
                document.querySelector(".GradingQuestionText.BorderColor").innerText += "\\n text to add"
                clearInterval(gt);
            }
        },100)
    }
});

To user: ahmedA
This is exactly what i was looking for. How to add the text to class .GradingQuestionText.BorderColor (upon inspection, thats the new class that gets added on the feedback page.)
I just didnt know which event to call so that i can modify/append the existing text.
I will try this and get back to you.
To User: Tom.
I agree that the picture would help clarifying the question. I will see if i can add an image that explains my question in a much better way.

The following code works first time when clicking the next button.
After answering the question, user presses the next button. This triggers the listener to append the feedback text and this text is appended to the existing question text.
Now after seeing this new feedback on the scoring page, if the user presses the back button, and then chooses a different answer and then clicks the next button, then the feedback text is not being added.

Qualtrics.SurveyEngine.addOnReady(function()
{
document.querySelector("#NextButton").addEventListener("click", grading_text);
  qid = this.questionId;
  var feedbackText = "My feedback Text";
    var gt = setInterval(function (){
      if(document.getElementById(qid).className == "Grading"){
        document.querySelector(".GradingQuestionText.BorderColor").innerText += feedbackText;
        clearInterval(gt);
      }
    },100)
  }
});



Userlevel 7
Badge +21

https://www.qualtrics.com/community/discussion/comment/32959#Comment_32959its surprising that it is even working the first time because you haven't defined the function which is supposed to execute onclick.

Ahmed.
I probably missed copying that line of code in the editor. Whats the best way for this function to get triggered if user goes back and then clicks the next button ?
Here is the actual code
Qualtrics.SurveyEngine.addOnReady(function () {
    document.querySelector("#NextButton").addEventListener("click", grading_text);
    qid = this.questionId;


    function grading_text(){
        var gt = setInterval(function (){
            if(document.getElementById(qid).className == "Grading"){
                document.querySelector(".GradingQuestionText.BorderColor").innerText += "Additional Text"
                clearInterval(gt);
            }
        },100)
    }
});

Also, i tried the following as well. The next does gets called, but the new text does not appear the second time.
Qualtrics.SurveyEngine.addOnPageSubmit(function(type)
{

if(type == "next")
{

  alert("here");
//document.querySelector("#NextButton").addEventListener("click", grading_text);
  qid = this.questionId;
  var addltext= "hello this is a new text";
grading_text();
  function grading_text(){
    var gt = setInterval(function (){
      if(document.getElementById(qid).className == "Grading"){
        document.querySelector(".GradingQuestionText.BorderColor").innerText += addltext;
        clearInterval(gt);
      }
    },100)
  }
}
});

Userlevel 7
Badge +21

I pasted the first code. And it's working no matter how many times I do back and next. So, there's a possibility that the issue may lie with your browser.
I modified the code a bit to add a random string, so it's still working. You can also try this, to check where the problem lies:
Qualtrics.SurveyEngine.addOnReady(function () {
    document.querySelector("#NextButton").addEventListener("click", grading_text);
    qid = this.questionId;
    function grading_text(){
        var gt = setInterval(function (){
console.log("not yet");

            if(document.getElementById(qid).className == "Grading"){
r = Math.random().toString(36).substring(7);
console.log(r);
                document.querySelector(".GradingQuestionText.BorderColor").innerText +="\\n"+ r;
                clearInterval(gt);
            }
        },100)
    }
});
On a general note, these kind of debugging scenarios require that you provide as much information as possible. What kind of question are you using? Are you using carry forward choices etc. etc. Since, the backend is close a black box, if I can't exactly replicate what you are doing, I won't encounter the problems you face.
PS: The

setInterval 
approach isn't recommended if you are trying to get users to go back and forth, it may lead to some instability. For one off, it's okay.

Userlevel 7
Badge +27

The Grading page is a new page. You can add an addOnload function to the Look & Feel header to reformat it with JS. I believe at least one reason the setInterval() approach is problematic is because the clearInterval(gt) function fails due to the scope of gt. I haven't tried it, but I think gt is undefined by the time clearInterval() is executed.


I tried the above code , but cannot make it to work the second time the user goes back and then clicks next. I copied the exact code you have.
I created a brand new simple question with 3 possible choices. Set score to 1 for the first choice. Add javascript to that question with the code above.
I have attached images that hopefully helps in troubleshooting. Second time i do see an error in the console log.
As far as the other approach, can you elaborate where should the javascript be placed.
If i add a code on the addOnLoad page, its not being called when the grading page loads. 
Image1.PNGGradingPage-FirstTime.PNGGradingPage-SecondTime.PNGError-SecondTime.PNGError2.PNG

Userlevel 7
Badge +27

To add JS to the Look & Feel header, edit the header in source mode (<>) and add the script inside a

If i comment the line below (and the corresponding brace)
//if(document.getElementById(qid).className == "Grading"){
i can see the text now if the user navigates back and forth. So is that line necessary?
Thanks!


Userlevel 7
Badge +21

Screengrab.ziphttps://www.qualtrics.com/community/discussion/comment/32987#Comment_32987I'm using the code here. You can see the screen grab to see that it's working.

Userlevel 7
Badge +21

https://www.qualtrics.com/community/discussion/comment/32998#Comment_32998Let's see the flow of the code. After one clicks the next button, the function checks the class of the element

qid
. If it is equal to
grading
, it changes the text and stops looking, if it is not, it checks the class again after 100ms. 
If you remove the if condition, the function will attempt to change the text only once. If
.GradingQuestionText.BorderColor
is present, it will succeed, if not it will throw an error. In either case, it will stop looking.
Ideally you shouldn't be getting the error shown in screenshots, because this implies, that the question itself is no longer present on the page, which is just weird. I would recommend, adding another if condition to check if the element exists:
Qualtrics.SurveyEngine.addOnReady(function () {
    document.querySelector("#NextButton").addEventListener("click", grading_text);
    qid = this.questionId;
    function grading_text(){
        var gt = setInterval(function (){
if(document.getElementById(qid)==null){console.log("missing");}
if(document.getElementById(qid)!=null){
if(document.getElementById(qid).className == "Grading"){
r = Math.random().toString(36).substring(7);
console.log(r);
document.querySelector(".GradingQuestionText.BorderColor").innerText +="\\n"+ r;
clearInterval(gt);
}
}
        },100)
    }
});
I tried the code above at different resolutions, even at 1ms, I couldn't replicate your problem.

I put a console.log(qid) after this line var qid=this.questionId
It outputs the value when i first enter the question.
However its null, if user clicks the next button, sees the grading page and then comes back to the question page by clicking the back button. 
Not sure why the questionId is null when the back button is pressed. 
qidnull.PNG

Userlevel 7
Badge +21

https://www.qualtrics.com/community/discussion/comment/33009#Comment_33009Sorry can't replicate this problem. Try with different browsers, turn off any ad blockers that you have.

qid 
should never be null.

Userlevel 7
Badge +27

qid
has a similar scope issue to the
gt
issue I mentioned above...it is local to the addOnReady function on the first page. Grading is on the second page. Using setInterval probably isn't the best approach.

I created a brand new survey with just one question in it. Still getting the same null id issue.
Also TomG I added a piece of code in the look and feel section as you had mentioned (i tried in both places onready and onload)
Unfortunately i still get qid as null.
Qualtrics.SurveyEngine.addOnload(function()
{
 var qid = this.questionId;
 console.log(qid);
});
Qualtrics.SurveyEngine.addOnReady(function()
{
 var qid = this.questionId;
 console.log(qid);
});

Userlevel 7
Badge +21

https://www.qualtrics.com/community/discussion/comment/33012#Comment_33012I'm a little confused about the scope issue.

gt 
should not have a scope problem, since it is being called within itself, and hence will always exist when it is referred to.
About
qid
, as you can see from my demo and the attached screenshot, the problem only occurs when the next button is pressed the second time, i.e. after the back button is pressed. If there was a scope issue, it wouldn't have worked the first time also. Also, as far as my understanding of the internal functioning goes,
this 
refers to the global scope of the
addOnload 
and other functions, i.e. the question. Hence, if the script is throwing an error, it is being called from the question, therefore
qid 
should not be null. Am I correct here?
While, I agree that the setInterval approach is generally problematic, the screenshot with the error message shows that not yet is only logged once, hence the interval is being cleared, so it isn't the interval that is spilling over. Is this reasoning correct?
I don't have a lot of experience with JS, it would be nice if you could share your thoughts on these. Thanks.

Userlevel 7
Badge +27

That’s because addOnload (or addOnReady) is not associated with a specific question when added to the header.

What would be the way to make this work then? I guess i dont follow your second approach.

Userlevel 7
Badge +27

https://www.qualtrics.com/community/discussion/comment/33016#Comment_33016You don't need the question object (this) to find the elements you are interested in. For example, to find all the graded questions on a page, you could do this:
var gqs = jQuery(".Grading");

Userlevel 7
Badge +27

https://www.qualtrics.com/community/discussion/comment/33014#Comment_33014When you use var X in a function, that variable is local to the function. If there is a function within that parent function then X is global in the child function. In the setInterval example, both qid and gt are global in the setInterval anonymous function (i.e., the function that is the first argument of setInterval). I believe what is happening is that while the setInterval function continues to run the parent function that is local to the page goes away when pages are switched and that results in the global variables being null.

Leave a Reply