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

JS codes works when preview question, but fail when preview whole block.

  • November 22, 2024
  • 2 replies
  • 65 views

Forum|alt.badge.img+5

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

Best answer by ahmedA

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;
	}

 

View original

2 replies

Forum|alt.badge.img+22
  • Level 7 ●●●●●●●
  • 2028 replies
  • Answer
  • November 25, 2024

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;
	}

 


Forum|alt.badge.img+3
  • Level 2 ●●
  • 14 replies
  • January 10, 2025

I am having the same issue! Could someone please look at my code as well?

 


Leave a Reply