Search code examples
javascriptqualtrics

How to customize values in a qualtrics' slider question?


I'm trying to custom a slider question in qualtrics. I am working with a question scaled in 4 increments (0, 25, 50, 75, 100), where the answers are snaped to increments, so I can make a Likert question more visual (so using labels as "Strongly disagree", "Neutral" and "Strongly agree"). However, I'd like to change the value shown at each bar, that refers to the numeric increments by default, presenting instead a custom text for each option (for example: "Strongly disagree", "somewhat disagree", "Neutral", "somewhat agree" and "Strongly agree").

After some research, I guess the only way to implement this is through javascript. However, I have no idea of this language and only found this code that I'd need to modify:

Qualtrics.SurveyEngine.addOnload(function()
{
jQuery('.ResultsInput').change(function()
{
updateTT(jQuery(this));
});

jQuery('.trackHolderRel').mousedown(function()
{
updateTT(jQuery(this));
});

function updateTT(element)
{
console.log(jQuery(element).find('.sliderToolTipBox').length)
if(jQuery(element).find('.sliderToolTipBox').length==1)
jQuery(element).find('.sliderToolTipBox').parent().append('<div class="sliderToolTipBox">2</div>')
jQuery(element).find('.sliderToolTipBox').eq(0).hide();
jQuery(element).find('.sliderToolTipBox').eq(1).html('Strongly disagree')
}

});

I guess it's a silly thing (hopefully) but I don't know how to proceed. Right now, it's always showing "Strongly disagree" for every option, as you can see in the picture. Also, when i select the left option, half of the text is cutted off the window, but this would rather be a secondary problem...

enter image description here

I'd very much appreciate your help! Thanks :)


Solution

  • You might be able to do it like this.

    const answers = {
        0: "Strongly disagree",
        25: "Disagree",
        50: "Neutral",
        75: "Agree",
        100: "Strongly agree"
    };
    
    function updateTT(element,message) {
        console.log(jQuery("div.sliderToolTipBox:last-child"));
        let toChange = element.parent().find("div.sliderToolTipBox:last-child");
        if(toChange.length > 0) {
            toChange.html(message);
        // The mobile version will fail the previous check, we need to handle this differently
        } else {
            let mobileTooltip = element.parent().find("div.sliderToolTipBox");
            if(mobileTooltip.length == 1) {
                mobileTooltip.html(message);
            }
        }
    }
    
    jQuery(document).on("change","input[name*=\"QR~QID56\"]",function() {
        let val = jQuery(this).val();
        let txt = answers[val];
    
        updateTT(jQuery(this),txt);
    });
    

    In order for this to work, you would have to remove the mousedown event handler, since that's reverting the text to what's in your original code (hardcoded text Strongly disagree).

    Also, by looking at the survey on the link you provided, I see that the input names follow the pattern of QR~QID56~<integer>. If that's the case for the rest of the inputs in your survey, you can use the partial attribute selector matching - that's what this part is for:

    "input[name*=\"QR~QID56\"]"
    

    Or you could just use the .ResultsInput.

    Another thing I'm relying on (again, by looking at the rendered code on the link you provided) is that the container for the text (Strongly disagree, Disagree, etc) is always div.sliderToolTipBox, and that it's always the last one (hence the :last-child selector).

    ... Unless you're viewing this on a mobile device. Then the :last-child selector will fail, as it will always return 0. I've added handling for that as well (the else bit with mobileTooltip).

    One more assumption is that you will always have these five options, and that the combo of value-label is an enum.

    Finally, the change event handler is attached to the jQuery(document), instead of a specific collection of nodes (inputs), since I'm not sure the inputs are present once the document has been loaded.