Adding buttons to my header using JS (worked, now broken) | XM Community
Solved

Adding buttons to my header using JS (worked, now broken)

  • 11 September 2018
  • 5 replies
  • 139 views

Userlevel 5
Badge +7
Good afternoon,

I had a user put a ticket in yesterday that I'm stumped on and wondered if anyone could spot my problem at a glance.


Code


`<p style="text-align: center;"><em><span style="font-size: 32px;"><strong>Inpatient Nursing Unit Characteristics Survey</strong></span></em><br />
 </p>

// New Header, Next, and Previous buttons
<div id="New" style="text-align: right; ">
<input id="PreviousButton" type="submit" value="Back" name="PreviousButton" title="Back"
onclick="Qualtrics.SurveyEngine.navClick(event, 'PreviousButton')">
<input id="NextButton" type="submit" value="Next" name="NextButton" title="Next" onclick=
"Qualtrics.SurveyEngine.navClick(event, 'NextButton')">
<style>`


Backstory


This code worked in mid-July at the very least; trying to figure out what broke it. I can re-code this ~4 different ways to accomplish the same task, but I want to know why it's broken now, as it looks to me like nothing's wrong. This code puts two custom buttons in the header of the survey, a next and a back, of course. These buttons are throwing a reference error: "Qualtrics is not defined at HTMLInputElement.onclick ([mySurveyId])", so Chrome (also tested in Firefox and IE with same results) doesn't know what _Qualtrics[.SurveyEngine.navClick]_ is or what it's referencing. The JS variable _This_ is 'undefined' any way I run it because the scope is above a specific question level.

I dug into the JSON WebPack file attached to the default >> Next Button and found the reference to the navClick function call:
`navClick: function(event, buttonName) {
return event = $.Event(event),
"NextButton" == buttonName && Page && Page.next(),
"PreviousButton" == buttonName && Page && Page.prev(),
event.preventDefault(),
!1`

I can't say I understand all of this, but I understand the logic behind it. To me, the onclick event looks correct, but the browser doesn't know how to interrupt Qualtrics Class APIs. Another thing I should mention, this survey has a Table of Contents 3 pages in (after a password entry page and a welcome page), and once inside the ToC, the custom buttons work fine. The default buttons are being hidden for reasons I'm not sure why; I believe they are using them as a "Master Submit" button. For the sake of testing, I commented the code to hide these, but I can't use them in my solution. Any wisdom as to why the custom buttons don't work on the first two pages? Anything you can offer would be much appreciated, thank you! I'd be happy to provide more info as needed!

- Jeremy
icon

Best answer by AnthonyR 11 September 2018, 20:51

View original

5 replies

Userlevel 7
Badge +7
Try using this in your header:

<p style="text-align: center;"><em><span style="font-size: 32px;"><strong>Inpatient Nursing Unit Characteristics Survey</strong></span></em><br />
 </p>

<div id="Buttons" role="navigation"><input id="PreviousButton" name="PreviousButton" title="Back" type="submit" value="Back" /> <input id="NextButton" name="NextButton" title="Next" type="submit" value="Next" />
<style type="text/css">
</style>
</div>
<script>
Qualtrics.SurveyEngine.addOnReady(function()
{
let that = this;
jQuery('#PreviousButton').on('click', function(){
that.clickPreviousButton();
})
jQuery('#NextButton').on('click', function(){
that.clickNextButton();
})
});
</script>

The problem is that the new survey engine has some loading issues, so we need to tie in those click events dynamically each time the page loads.

I also recommend hiding the previous button if it is the first page. if you need help making that happen let me know, shouldn't be much effort!
Userlevel 7
Badge +7
It is also worth noting that while this works, it is bad practice to have multiple elements with the same id on a page. you may consider giving these all a different id and tying in to that instead. This has a negative benefit of needing you to manually style these buttons though.
Userlevel 5
Badge +7
Hey Anthony, your solution works great and it improves the look of the buttons! I tried using a jQuery .clone() function to do the same thing, and the buttons looked great, but they weren't functional, possibly because of overlapping IDs. For anyone reading this later, I added this code at the end of the code snippet above to hide the default buttons:
`<style>
.Skin #Buttons:nth-child(5) {
visibility:hidden;
}
</style>`
(the section _:nth-child(5)_ would need to be modified so it hides the appropriate buttons. Without (5), that CSS filter would squash the buttons we just worked so hard to create.)

Your section `<style type="text/css"></style>`. Is that the step that actually applies the CSS to the buttons? Or is it adding the <div> with an id = Buttons, since the default buttons are set to the same id which the style sheet is looking for..?

Also, hiding the Back button on the first page would be great! I've done work with displaying/hiding elements based on 1st page load vs nth page load, but I doubt it's the most efficient way. I would use Embedded Data, but I'd love to know how'd you do it.

Thanks so much for the help on this!
Userlevel 7
Badge +7
> @JeremyK said:
> Hey Anthony, your solution works great and it improves the look of the buttons! I tried using a jQuery .clone() function to do the same thing, and the buttons looked great, but they weren't functional, possibly because of overlapping IDs. For anyone reading this later, I added this code at the end of the code snippet above to hide the default buttons:
> `<style>
> .Skin #Buttons:nth-child(5) {
> visibility:hidden;
> }
> </style>`
> (the section _:nth-child(5)_ would need to be modified so it hides the appropriate buttons. Without (5), that CSS filter would squash the buttons we just worked so hard to create.)
>
> Your section `<style type="text/css"></style>`. Is that the step that actually applies the CSS to the buttons? Or is it adding the <div> with an id = Buttons, since the default buttons are set to the same id which the style sheet is looking for..?
>
> Also, hiding the Back button on the first page would be great! I've done work with displaying/hiding elements based on 1st page load vs nth page load, but I doubt it's the most efficient way. I would use Embedded Data, but I'd love to know how'd you do it.
>
> Thanks so much for the help on this!

Interestingly if you are actually just trying to move the buttons, this may be a simpler solution that handles the hiding of previous buttons and whatnot.

I had considered that you may have wanted to have them at the top and bottom!

Try this code out for moving the buttons from the bottom to the top:

<div id="newButtonDest" style="min-height: 74px"> </div>
<script>
Qualtrics.SurveyEngine.addOnReady(function()
{
let buttonContainer = jQuery('#Buttons');
buttonContainer.css('margin-top', '0');
jQuery('#newButtonDest').html(buttonContainer);
});
</script>

In answer to your question, the default CSS is being applied since I added the Buttons id to the containing div. I didn't have to style them at all.
Badge

https://www.qualtrics.com/community/discussion/comment/6191#Comment_6191Hello Anthony,
Just connecting into this feed--
Is it possible to get some more details on how to remove the back button on the first page?
I am looking to have the the back button at the top of all pages except for the first. But to keep the back and front buttons at the bottom of the page.
Greatly appreciate any support!
Thank you!
Jess

Leave a Reply