Using Javascript to force response on dropdown questions in Javascript/HTML table? | XM Community
Skip to main content

I made a Javascript/HTML table which has multiple dropdown questions (labeled as "dropdown1_left", "dropdown1_right", etc.) within the table that I want to be required. I have not been able to figure out how to make this work. Below is my code for this specific function. When I take the survey, the console log says “Listener must be a named function.” so this may be causing the problem. When I hit the next page button, I do get a pop-up saying “Please make a selection for all required dropdowns.” but it still moves on to the next page. So some level of the validation seems to be working but ultimately not the most important part (I want it to not allow users to go to the next page until all dropdowns are answered).

Any thoughts on how to make this work? I’m pretty new to Javascript and especially using it in Qualtrics so I am hoping to learn how to code this in. Thank you so much in advance.

 

Qualtrics.SurveyEngine.addOnPageSubmit(function(type) {
    if (type === "next") { // Trigger validation only when "Next" is clicked
        var requiredDropdownIDs = i
            "dropdown1_left", "dropdown1_right", "dropdown2_left", "dropdown2_right", 
            "dropdown3_left", "dropdown3_right", "dropdown4_left", "dropdown4_right",
            "dropdown5_left", "dropdown5_right", "dropdown6_left", "dropdown6_right", 
            "dropdown7_left", "dropdown7_right", "dropdown8_left", "dropdown8_right", 
            "dropdown9_left", "dropdown9_right", "dropdown10_left", "dropdown10_right", 
            "dropdown11_left", "dropdown11_right", "dropdown12_left", "dropdown12_right", 
            "dropdown13_left", "dropdown13_right", "dropdown14_left", "dropdown14_right", 
            "dropdown15_left", "dropdown15_right"
        ];

        var isValid = true; // Flag to track overall validation

        // Iterate through each dropdown and validate its value
        requiredDropdownIDs.forEach(function(id) {
            var dropdown = document.getElementById(id);

            // Log each dropdown ID and its value for debugging
            console.log("Checking dropdown:", id, "Value:", dropdown ? dropdown.value : "Not Found");

            if (dropdown && dropdown.value === "Select an option") {
                isValid = false; // Mark as invalid if dropdown is unselected
                dropdown.style.border = "2px solid red"; // Highlight unselected dropdown
            } else if (dropdown) {
                dropdown.style.border = ""; // Clear the border if dropdown is valid
            }
        });

        // If any dropdown is unselected, prevent form submission
        if (!isValid) {
            alert("Please make a selection for all required dropdowns.");
            jQuery("#NextButton").hide();
        }

        // Log success if all validations pass
        console.log("All dropdowns are selected. Proceeding to next page.");
    }
});

I made a Javascript/HTML table which has multiple dropdown questions (labeled as "dropdown1_left", "dropdown1_right", etc.) within the table that I want to be required.

@rgroth We don’t know what is your custom Javascript/HTML table and also it might be deciding factor.
Also, there’s easier & more manageble way of making table contain multiple question via Side-by-side question. I think you should give it a try because the validation is built-in already.
Side by Side Question


Thank you ​@Nam Nguyen for your response. I did not originally include my code because I cannot share all of the content, but I have provided it below with some information removed. I am unable to use the side-by-side question format because it does not work for the specific functions I need. I need to have a table with three columns, where the response to a dropdown question in the leftmost column determines text that is populated in the middle column, and whether another dropdown question appears in the rightmost column. That aspect of the function is working well, but I am still struggling to make it so all the questions are required.

I put my entire JavaScript code below. Starting with the line “Qualtrics.SurveyEngine.addOnPageSubmit(function(type) {“ is where I have attempted to make the questions required but it is not working -- as I said in my original post, if I hit the next page button, I do get a pop-up saying “Please make a selection for all required dropdowns.” but it still moves on to the next page. How can I code this such that it keeps the user on that page and does not allow them to go to the next page until they have answered the required questions?

 

Qualtrics.SurveyEngine.addOnload(function() {
    // Object to hold the text values for each option in each row
    var textValues = {
        "dropdown1_left": {
            "Option 1": "",
            "Option 2": ""
        },
        "dropdown2_left": {
            "Option 1": "",
            "Option 2": ""
        },
         "dropdown3_left": {
            "Option 1": "",
            "Option 2": ""
        },
         "dropdown4_left": {
            "Option 1": "",
            "Option 2": ""
        },
         "dropdown5_left": {
            "Option 1": "",
            "Option 2": ""
         },
         "dropdown6_left": {
            "Option 1": "",
            "Option 2": ""
         },
         "dropdown7_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown8_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown9_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown10_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown11_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown12_left": {
           "Option 1": "",
            "Option 2": ""
         },
        "dropdown13_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown14_left": {
            "Option 1": "",
            "Option 2": ""
         },
        "dropdown15_left": {
            "Option 1": "",
            "Option 2": ""
         },
        
            };

    // Function to dynamically update the text field based on the dropdown selection
    function updateText(choiceId, textId, embeddedDataName) {
        var choice = document.getElementById(choiceId);
        var text = document.getElementById(textId);

        // Add event listener to the dropdown
        choice.addEventListener("change", function() {
            var selectedValue = choice.value;

            // Check if the selected value corresponds to any text values
            if (textValueschoiceId] && textValuesechoiceId]yselectedValue]) {
                text.value = textValuesychoiceId])selectedValue];  // Populate with the corresponding text
            } else {
                text.value = "";  // Clear the text if no valid option is selected
            }
            
            // Store the selected left dropdown value in the embedded data field
            Qualtrics.SurveyEngine.setJSEmbeddedData(embeddedDataName, selectedValue);
            
        });
    }
    
    
     // Function to capture both left and right dropdown selections and store in embedded data fields
    function updateDropdowns(leftChoiceId, rightChoiceId, rightTextId, leftEmbeddedData, rightEmbeddedData) {
        var leftChoice = document.getElementById(leftChoiceId);
        var rightChoice = document.getElementById(rightChoiceId);
        var rightText = document.getElementById(rightTextId);
        
         // Initially hide the right dropdown
        rightChoice.style.display = "none";
        rightText.style.display ="none";
         
         // Capture the left dropdown value
        leftChoice.addEventListener("change", function() {
            var selectedValue = leftChoice.value;
            console.log("Left dropdown selected value (ID: " + leftChoiceId + "): " + selectedValue);

              // Show the right dropdown only if "Option 1" is selected, otherwise hide and reset it
            if (selectedValue === "Option 1") {
                rightChoice.style.display = "inline";  // Show right dropdown
                rightText.style.display = "inline";
            } else {
                rightChoice.style.display = "none";    // Hide right dropdown
                rightText.style.display="none";
                rightChoice.value = "";                // Clear the right dropdown selection
                Qualtrics.SurveyEngine.setJSEmbeddedData(rightEmbeddedData, ""); // Clear embedded data
            }
            
             // Store the selected left dropdown value in the embedded data field
            Qualtrics.SurveyEngine.setJSEmbeddedData(leftEmbeddedData, selectedValue);
        });
    
         // Capture the right dropdown value (if it becomes visible) 
        rightChoice.addEventListener("change", function() {
            var selectedValue = rightChoice.value;
            console.log("Right dropdown selected value (ID: " + rightChoiceId + "): " + selectedValue);


            // Store the selected right dropdown value in the embedded data field
            Qualtrics.SurveyEngine.setJSEmbeddedData(rightEmbeddedData, selectedValue);
        });
    }
    

    // Call the updateText function for each row
    updateText("dropdown1_left", "text1", "PDAtopic1");
    updateText("dropdown2_left", "text2", "PDAtopic2");
    updateText("dropdown3_left", "text3", "PDAtopic3");
    updateText("dropdown4_left", "text4", "PDAtopic4");
    updateText("dropdown5_left", "text5", "PDAtopic5");
    updateText("dropdown6_left", "text6", "PDAtopic6");
    updateText("dropdown7_left", "text7", "PDAtopic7");
    updateText("dropdown8_left", "text8", "PDAtopic8");
    updateText("dropdown9_left", "text9", "PDAtopic9");
    updateText("dropdown10_left", "text10", "PDAtopic10");
    updateText("dropdown11_left", "text11", "PDAtopic11");
    updateText("dropdown12_left", "text12", "PDAtopic12");
    updateText("dropdown13_left", "text13", "PDAtopic13");
    updateText("dropdown14_left", "text14", "PDAtopic14");
    updateText("dropdown15_left", "text15", "PDAtopic15");

    
      // Call the updateDropdowns function for each row to capture both left and right dropdown responses
    updateDropdowns("dropdown1_left", "dropdown1_right", "rightText1", "PDAtopic1", "PDAimportance1");  // For row 1
    updateDropdowns("dropdown2_left", "dropdown2_right", "rightText2", "PDAtopic2", "PDAimportance2");  // For row 2
    updateDropdowns("dropdown3_left", "dropdown3_right", "rightText3", "PDAtopic3", "PDAimportance3");
    updateDropdowns("dropdown4_left", "dropdown4_right", "rightText4", "PDAtopic4", "PDAimportance4");
    updateDropdowns("dropdown5_left", "dropdown5_right", "rightText5", "PDAtopic5", "PDAimportance5");
    updateDropdowns("dropdown6_left", "dropdown6_right", "rightText6", "PDAtopic6", "PDAimportance6");
    updateDropdowns("dropdown7_left", "dropdown7_right", "rightText7", "PDAtopic7", "PDAimportance7");
    updateDropdowns("dropdown8_left", "dropdown8_right", "rightText8", "PDAtopic8", "PDAimportance8");
    updateDropdowns("dropdown9_left", "dropdown9_right", "rightText9", "PDAtopic9", "PDAimportance9");
    updateDropdowns("dropdown10_left", "dropdown10_right", "rightText10", "PDAtopic10", "PDAimportance10");
    updateDropdowns("dropdown11_left", "dropdown11_right", "rightText11", "PDAtopic11", "PDAimportance11");
    updateDropdowns("dropdown12_left", "dropdown12_right", "rightText12", "PDAtopic12", "PDAimportance12");
    updateDropdowns("dropdown13_left", "dropdown13_right", "rightText13", "PDAtopic13", "PDAimportance13");
    updateDropdowns("dropdown14_left", "dropdown14_right", "rightText14", "PDAtopic14", "PDAimportance14");
    updateDropdowns("dropdown15_left", "dropdown15_right", "rightText15", "PDAtopic15", "PDAimportance15");
});

Qualtrics.SurveyEngine.addOnPageSubmit(function(type) {

    if (type === "next") { // Trigger validation only when "Next" is clicked
        var requiredDropdownIDs = "
            "dropdown1_left", "dropdown1_right", "dropdown2_left", "dropdown2_right", 
            "dropdown3_left", "dropdown3_right", "dropdown4_left", "dropdown4_right",
            "dropdown5_left", "dropdown5_right", "dropdown6_left", "dropdown6_right", 
            "dropdown7_left", "dropdown7_right", "dropdown8_left", "dropdown8_right", 
            "dropdown9_left", "dropdown9_right", "dropdown10_left", "dropdown10_right", 
            "dropdown11_left", "dropdown11_right", "dropdown12_left", "dropdown12_right", 
            "dropdown13_left", "dropdown13_right", "dropdown14_left", "dropdown14_right", 
            "dropdown15_left", "dropdown15_right"
        ];

        var isValid = true; // Flag to track overall validation

        // Iterate through each dropdown and validate its value
        requiredDropdownIDs.forEach(function(id) {
            var dropdown = document.getElementById(id);

            // Log each dropdown ID and its value for debugging
            console.log("Checking dropdown:", id, "Value:", dropdown ? dropdown.value : "Not Found");

            if (dropdown && dropdown.value === "Select an option") {
                isValid = false; // Mark as invalid if dropdown is unselected
                dropdown.style.border = "2px solid red"; // Highlight unselected dropdown
            } else if (dropdown) {
                dropdown.style.border = ""; // Clear the border if dropdown is valid
            }
        });

        // If any dropdown is unselected, prevent form submission
        if (!isValid) {
            alert("Please make a selection for all required dropdowns.");
            this.disableNextButton();
        }

        // Log success if all validations pass
        console.log("All dropdowns are selected. Proceeding to next page.");
    }
    })


@rgroth,

Your code attempts to disable the next button after it has already been clicked (clicking next fired addOnPageSubmit).

An alternative approach would be to disable the next button in addOnReady and add an event handler to enable the next button when all dropdowns have been selected.


@TomG thank you so much. Would you be able to give an example of how to write this code?


Leave a Reply