Java For Star Question and Forced response resetting starts - how to prevent | XM Community
Skip to main content
Solved

Java For Star Question and Forced response resetting starts - how to prevent


Forum|alt.badge.img+1

Hi all!!

About 3 years ago there was a post about setting up a Star question instead of the bubbles. 1 year ago some Qualtrics gurus gave Java and CSS to override the multiple choice question set to be stars. It works great - if you want to do that check it out!

 

BUT - We also put forced response questions in our survey. When you take the survey and fill in your star rating the stars turn yellow. If you skip a question that is required and Qualtrics makes you go back to retake the question - all your star ratings turn back to grey as if you did not select them. The data is still there. During testing, I did not go back and repopulate the stars and the data captured my first input. But this will not be a good customer experience. So if anyone has code (and an explanation for noob coders on where to put it) that can stop the stars from resetting their color - that would be AMAZING!!

 

Thanks

Best answer by Tom_1842

Hi ​@Tob, I believe you are referring to this post, and I see what you mean about the highlighting being removed when the page loads. The updateStars function only runs when a star is clicked, so I've made an adjustment so that it runs when the page is loaded as well. Try using the below JS in the OnReady section:

Qualtrics.SurveyEngine.addOnReady(function()
{
	/*Place your JavaScript here to run when the page is fully displayed*/
const questionBody = document.querySelector('#'+this.questionId+' .QuestionBody');
const radios = questionBody.querySelectorAll('#'+this.questionId+' input[type="radio"]');

// Create top left label
const topLeftLabel = document.createElement('div');
topLeftLabel.className = 'label top-left';
topLeftLabel.innerText = 'Left Label 1';
questionBody.appendChild(topLeftLabel);

// Create top right label
const topRightLabel = document.createElement('div');
topRightLabel.className = 'label top-right';
topRightLabel.innerText = 'Right Label 1';
questionBody.appendChild(topRightLabel);	

// Create star rating container
const starContainer = document.createElement('div');
starContainer.className = 'star-rating';
questionBody.appendChild(starContainer);

// Create stars
 radios.forEach((radio, index) => {
        const star = document.createElement('span');
        star.className = 'star not-rated';
        star.innerHTML = '★'; // Star character
        star.dataset.value = radio.value;
        starContainer.appendChild(star);

        star.addEventListener('click', () => {
            radios[index].checked = true;
            updateStars(starContainer, index);
        });
    });

// Update stars on page load
const checkedRadioIndex = Array.from(radios).findIndex(radio => radio.checked);
if (checkedRadioIndex !== -1) {
    updateStars(starContainer, checkedRadioIndex);
}

    function updateStars(container, index) {
        const stars = container.querySelectorAll('.star');
        stars.forEach((star, i) => {
            if (i <= index) {
                star.classList.remove('not-rated');
            } else {
                star.classList.add('not-rated');
            }
        });
    }
});

And the CSS:

.label {
    font-size: 14px;
}

.top-left {
float: left;
padding-top: 10px;
padding-left: 20px;
}

.top-right {
float: right;
padding-top: 10px;
padding-right: 20px;
}

.star-rating{
width: 100%;
display: flex; 
justify-content: center; 
align-items: center;
}

.star-rating .star {
    font-size: calc(50px + 2vw);
    cursor: pointer;
    color: gold;
    display: inline-block;
    margin-right: 5px;
}

.star-rating .star.not-rated {
    color: #e3e3e3;
}

/*update with questionIDs*/
#QID1 .ChoiceStructure, #QID2 .ChoiceStructure {
display: none;
}

 

View original

2 replies

Tom_1842
Level 8 ●●●●●●●●
Forum|alt.badge.img+28
  • Level 8 ●●●●●●●●
  • 876 replies
  • Answer
  • March 11, 2025

Hi ​@Tob, I believe you are referring to this post, and I see what you mean about the highlighting being removed when the page loads. The updateStars function only runs when a star is clicked, so I've made an adjustment so that it runs when the page is loaded as well. Try using the below JS in the OnReady section:

Qualtrics.SurveyEngine.addOnReady(function()
{
	/*Place your JavaScript here to run when the page is fully displayed*/
const questionBody = document.querySelector('#'+this.questionId+' .QuestionBody');
const radios = questionBody.querySelectorAll('#'+this.questionId+' input[type="radio"]');

// Create top left label
const topLeftLabel = document.createElement('div');
topLeftLabel.className = 'label top-left';
topLeftLabel.innerText = 'Left Label 1';
questionBody.appendChild(topLeftLabel);

// Create top right label
const topRightLabel = document.createElement('div');
topRightLabel.className = 'label top-right';
topRightLabel.innerText = 'Right Label 1';
questionBody.appendChild(topRightLabel);	

// Create star rating container
const starContainer = document.createElement('div');
starContainer.className = 'star-rating';
questionBody.appendChild(starContainer);

// Create stars
 radios.forEach((radio, index) => {
        const star = document.createElement('span');
        star.className = 'star not-rated';
        star.innerHTML = '&#9733;'; // Star character
        star.dataset.value = radio.value;
        starContainer.appendChild(star);

        star.addEventListener('click', () => {
            radios[index].checked = true;
            updateStars(starContainer, index);
        });
    });

// Update stars on page load
const checkedRadioIndex = Array.from(radios).findIndex(radio => radio.checked);
if (checkedRadioIndex !== -1) {
    updateStars(starContainer, checkedRadioIndex);
}

    function updateStars(container, index) {
        const stars = container.querySelectorAll('.star');
        stars.forEach((star, i) => {
            if (i <= index) {
                star.classList.remove('not-rated');
            } else {
                star.classList.add('not-rated');
            }
        });
    }
});

And the CSS:

.label {
    font-size: 14px;
}

.top-left {
float: left;
padding-top: 10px;
padding-left: 20px;
}

.top-right {
float: right;
padding-top: 10px;
padding-right: 20px;
}

.star-rating{
width: 100%;
display: flex; 
justify-content: center; 
align-items: center;
}

.star-rating .star {
    font-size: calc(50px + 2vw);
    cursor: pointer;
    color: gold;
    display: inline-block;
    margin-right: 5px;
}

.star-rating .star.not-rated {
    color: #e3e3e3;
}

/*update with questionIDs*/
#QID1 .ChoiceStructure, #QID2 .ChoiceStructure {
display: none;
}

 


Forum|alt.badge.img+1
  • Author
  • 1 reply
  • March 12, 2025

You are the best!! Thank you. That totally worked!


Leave a Reply