JS codes works when preview question, but fail when preview whole block. | XM Community
Skip to main content

Dear all,

I am design an experiment. My survey question is simple in nature, which is in text-entry type. I have created the html part for the description.

<style>

.bg_color{
background-color: #FCFC9C;
}

table.centered-table {
width: 648px;
margin: auto;
border-collapse: collapse;
text-align: center;
}
table.centered-table th, table.centered-table td {
text-align: center;
}
table.centered-table th {
border-bottom: 2px solid black;
font-weight: bold;
padding: 20px;
}
table.centered-table .border-white {
border-bottom: 2px solid white;
}
table.centered-table .border-light {
border-bottom: 2px solid #f1f1f1;
}

.gray-text { color: gray; }
.red-text { color: red; }
.blue-text { color: blue; }

.transparent-button {
background-color: transparent;
border: none;
padding: 20px;
cursor: pointer;
}

</style>

<table class="centered-table">
<thead>
<tr>
<th class="red-text" style="width: 20%;">Set A</th>
<th class="border-white" style="width: 5%;"> </th>
<th class="blue-text" style="width: 30%;">Set B</th>
</tr>
<tr>
<th class="red-text" style="width: 20%;">100 Boxes</th>
<th class="border-white" style="width: 5%;">&nbsp;</th>
<th class="blue-text" style="width: 40%;">40 Boxes &nbsp; &nbsp; &nbsp; 60 Boxes</th>
</tr>
</thead>
<tbody>
<tr>
<td id="a1" class="red-text border-light">
<button class="transparent-button" style="color: red;">$25.00</button>
</td>
<td class="border-white">&nbsp;</td>
<td id="b1" class="blue-text border-light">
<button class="transparent-button" style="color: blue;">$25.00 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $0.00</button>
</td>
</tr>
<tr>
<td id="a2" class="red-text border-light">
<button class="transparent-button" style="color: red;">$24.00</button>
</td>
<td class="border-white">&nbsp;</td>
<td id="b2" class="blue-text border-light">
<button class="transparent-button" style="color: blue;">$25.00 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $0.00</button>
</td>
</tr>
<tr>
<td id="a3" class="red-text border-light">
<button class="transparent-button" style="color: red;">$23.00</button>
</td>
<td class="border-white">&nbsp;</td>
<td id="b3" class="blue-text border-light">
<button class="transparent-button" style="color: blue;">$25.00 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $0.00</button>
</td>
</tr>
</tbody>
</table>

I have also finished my JS codes:

Qualtrics.SurveyEngine.addOnload(function()
{
/*Place your JavaScript here to run when the page loads*/

var OutputField = document.getElementById("QR~"+this.questionId);
OutputField.style.display = "none";


// Get all red and blue buttons
let red_btns = document.querySelectorAll(".red-text>button");
let blue_btns = document.querySelectorAll(".blue-text>button");

// Variables to track the highlighted range
var xend = 0, yend = 0;

// Add event listeners to left (red) buttons
red_btns.forEach((item, i) => {
// Assign a custom attribute for button identification
item.setAttribute("left_id", i + 1);

// Add click event listener for red buttons
item.addEventListener("click", function (evt) {
// Get the ID of the clicked button
xend = +evt.target.getAttribute("left_id");
// Update background highlights
refreshBgColor(xend, yend);
});
});

// Add event listeners to right (blue) buttons
blue_btns.forEach((item, j) => {
// Assign a custom attribute for button identification
item.setAttribute("right_id", j + 1);

// Add click event listener for blue buttons
item.addEventListener("click", function (evt) {
let clicked = +evt.target.getAttribute("right_id");

if (clicked < xend) {
if (!yend) {
yend = xend;
}
xend = clicked - 1;
} else {
yend = clicked;
}

// Update background highlights
refreshBgColor(xend, yend);
});
});


/**
* Refresh background color highlights
* @param {*} xend - Last highlighted left (red) button
* @param {*} yend - Last highlighted right (blue) button
*/
function refreshBgColor(xend, yend) {
let ystart = xend + 1;

// Highlight left (red) buttons
setBgRange("red", 1, xend);

// Highlight right (blue) buttons
if (yend) {
setBgRange("blue", ystart, yend);
}
}

/**
* Highlight background color for a range of buttons
* @param {string} type - Button type ("red" or "blue")
* @param {number} start - Starting index
* @param {number} end - Ending index
*/
function setBgRange(type, start, end) {
// Get all buttons of the specified type
let btns = document.querySelectorAll(`.${type}-text>button`);

// Clear all previous highlights
document.querySelectorAll(`.${type}-text`).forEach(e => e.classList.remove("bg_color"));

// Highlight buttons within the specified range
btns.forEach(item => {
// Get the button index based on its attribute
let index = (type === "red" ? item.getAttribute("left_id") : item.getAttribute("right_id"));
index = parseInt(index);
start = parseInt(start);
end = parseInt(end);

// Add highlight class if within range
if (index >= start && index <= end) {
item.parentElement.classList.add("bg_color");
}
});
}

//calculate OutputField value
OutputField.value = end;
});

The purpose of my JS codes are mainly two folds:

  1. Highlighting the choice pattern.
  2. Record the switch point (from one side to another side), and store it as the output of this entry-text question.

Now, I can see my JS codes work (at least for the highlight function) when I preview this question. However, when I preview the block, which opens a page, the JS part does not work, including the highlighting part.

(I have tried to change addOnload to addOnReady, nothing changes.)

Your answer will be very appreciated. Thank you!

Best,

Elon

For the JS, your last few lines are the issue. Move the value assignment to inside the setBgRange function. It should look like this :

OutputField.value = end;
}
});

NOT:

}
OutputField.value = end;
});

 

You may also want to consider highlighting the row, so that the respodents are clear on what they are clicking. Adding this to the style tag would acheive that:

	table.centered-table tbody tr:hover {
background-color: lightgray;
}

 


Leave a Reply