Javascript only activates after refreshing page | XM Community
Skip to main content

Hi all,
I have a survey where I've implemented a simple counter to track the number of times a user clicks on any region of a Hot Spot element. I've set up a click event listener for the path elements of the hot spot SVG, and on click, I get the embedded data field

hs_ct
, increment by one, then set
hs_ct
with the updated value.
Here's a simple example: https://betterup.co1.qualtrics.com/jfe/form/SV_cTIkLpl3p9HHZtk
And here's the JS code for the hot spot item:
Qualtrics.SurveyEngine.addOnload(function()
{
   /*Place your JavaScript here to run when the page loads*/
});

Qualtrics.SurveyEngine.addOnReady(function()
{
   jQuery('path').on('click', function() {
      console.log('you clicked a region');

      var ct = parseInt(Qualtrics.SurveyEngine.getEmbeddedData("hs_ct"));
      console.log('counter before increment: ' + String(ct));

      ct = ct + 1;

      console.log('counter incremented by 1: ' + String(ct));

      Qualtrics.SurveyEngine.setEmbeddedData("hs_ct", ct);

      var newCt = Qualtrics.SurveyEngine.getEmbeddedData("hs_ct");
      console.log('counter set and then re-loaded, should show updated value: ' + String(newCt));

   });
});

Qualtrics.SurveyEngine.addOnUnload(function()
{
   /*Place your JavaScript here to run when the page is unloaded*/

});
My problem is that none of my Javascript code seems to execute, unless I refresh the page. After one refresh, everything works. (Subsequent refreshes also work fine.)
This behavior occurs both in Preview mode and when using a live, Published survey. It's not just a console issue either - without refreshing after the survey is loaded for the first time, the embedded data field
hs_ct
in a completed survey response does not reflect hot spot clicks - its value is zero.
If you open the Javascript console in your browser, you'll see that clicking on one of the four squares results in a set of console log entries. First, a message appears ("you clicked a region"), and then the click count is displayed, before and after incrementing and re-setting the ED field. But assuming the issue is reproducible, you won't see any console output on first load. Only after you reload will you see the console output showing up.
I've tried moving the code to the
onLoad
section (although I think it needs to be
onReady
because of when the SVG is constructed), that didn't make a difference. I also tested in FF and Chrome, on the off chance it was a browser issue. The issue is the same in both browsers.
I have thought about setting an auto-refresh on page load, but that feels pretty hacky. Any ideas on what's causing this issue?

Thanks,
Andrew

SVG elements take sometime to draw. So the first time the code runs, there's no path for jQuery to select. Therefore nothing happens. However, because you are refreshing your page, its already drawn and with the browser, it just places it there. I don't work a lot with SVGs so am not sure if there's a DOM API to capture "rendering complete" as an event, but you could try something like this:
let chk_svg = setInterval(() => {
    if (document.querySelectorAll("svg path").length === 4) {
        clearInterval(chk_svg);
        // Your Code Here //
    }
}, 200);


Thanks for the advice Ahmed. I tried out your solution, and while it appears that, in rare cases, the SVG actually does take a little longer to load (<1% of the time), there is actually a different cause for the issue I was seeing.
It turns out that Qualtrics redraws the entire Hot Spot SVG under certain conditions, like a screen resize. (I'm sure about screen resize, not sure about what other conditions might trigger a redraw) So actually just opening the Console to observe

console.log()
events was destroying the event handlers I'd set on the SVG
path
elements, because those
path
elements did not exist anymore. (And that's why the refresh was working, because I hadn't closed the Console window, so the screen size stayed the same.)
The solution I ended up with was to set the click event handler on
body
, and then check to see whether the
target
tag that triggers an event is a
path
tag. That way the tracking mechanism can survive an SVG redraw. (Notably, this approach also solves the initial SVG load time issue.)
   jQuery('body').on('click', function(e) {
      if (e.target.tagName == 'path') {
         // DO OPERATIONS ON SVG PATH ELEMENT
      }
   });


https://community.qualtrics.com/discussion/comment/38412#Comment_38412
Thanks for sharing this info, pretty interesting.


Leave a Reply