Javascript display logic for matrix table: hide row conditional on answer being piped in

I have a matrix table to which I'm piping in responses from several prior multiple choice (single response) questions. When a person answers anything other than "I don't know" to the prior questions, it works fine. However, when the person answers "I don't know" to any of those questions, I do not want the "I don't know" as a row to which the person can respond in the matrix table. In other words, I want the matrix table to only show rows for those questions to which a person did not give an "I don't know" answer. (So the number of rows will vary depending on the number of the person's "I don't know" answers to the prior questions.) I tried using display logic on the rows so that the rows would only display when "I don't know" was not selected, and this did hide the wording "I don't know," but the problem is that it did not hide the row itself so that now the row itself with the radio buttons is still there but it has no wording associated with it. How can I get rid of the whole row, including the radio buttons, when a person answers "I don't know" for that particular item? I think I need to put Javascript in. I tried the below from bits and pieces I got off the internet, but obviously it didn't work. I also need to include this snippet in there too jQuery(".choiceText").hide(); but I'm not sure where or how to include it. (This part does work.) Thanks for any help you can provide!

if ('${q://QID88~93/ChoiceGroup/SelectedChoices}'= ‘I don't know’)
{jQuery(("#QR~"+this.questionId+"~"+cell).replace(/~/g, "\~")).closest("td").find("*").hide();}

Tagged:

Best Answer

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭
    Accepted Answer

    @ResearchPsychologist said:
    Oh, I'm sorry: I misspoke. I do have "IS NOT SELECTED." The red circled area is where I chose "I don't know" on one of those previous questions and while the words "I don't know" are not displayed, as you can see, the row still is. See below

    That looks like you didn't force response on one or more of the previous questions so a blank item (no answer) is being piped. If I'm correct, an easy solution is to turn on force response on those questions.

Answers

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    Change closest("td").find("*") to closest("tr") to hide the entire row. You won't need to hide the choiceText since it is part of the row.

  • ResearchPsychologist
    edited July 2019

    Qualtrics.SurveyEngine.addOnload(function()
    {
    /Place your JavaScript here to run when the page loads/
    if ('${q://QID88~93/ChoiceGroup/SelectedChoices}'= ‘I don't know’)
    {jQuery(("#QR~"+this.questionId+"~"+cell).replace(/~/g, "\~")).closest("tr").hide();}
    jQuery(".choiceText").hide();
    });

    Error: "Invalid left-hand side in assignment." Any ideas on what I'm doing wrong? Am I missing a period or a parenthesis somewhere?

    Also, I need the choiceText part to address something else from another question. (The choices being piped in to this question need parts of them hidden: MexicoMexican ("choiceText""pipedText") is piped in, for example, and I need to hide the choiceText (Mexico) and display only the pipedText (Mexican).

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    You have an extra set of parens. Remove the ( immediately after jQuery and the ) before .closest. However, it doesn't look you assigned a value to the variable "cell".

    The choiceText hide line looks fine to me.

  • Hm. The same error is still appearing after I removed both of those parentheses. Is this because I haven't assigned a value to "cell"? What value should I be assigning to "cell"?

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    @ResearchPsychologist said:
    Hm. The same error is still appearing after I removed both of those parentheses. Is this because I haven't assigned a value to "cell"? What value should I be assigning to "cell"?

    Probably. I don't think you want to use cell at all. I think you just want to reference the choice row (i.e., the equivalent of QID88~93). I don't understand enough about what you are doing to understand why you aren't using carry forward or display logic.

  • ResearchPsychologist
    edited July 2019

    I'll try to give more info below.

    Question 1: "What country were you born in?" (Multiple Choice, Single Response)

    Choice 1:
    <span class="choiceText">Afghanistan< /span>< span class="pipeText">Afghan</span> (appears as AfghanistanAfghan)
    All the way to <span class="choiceText">Zimbabwe</span><span class="pipeText">Zimbabwean</span> (appears as ZimbabweZimbabwean)

    Javascript on Question 1:

    Qualtrics.SurveyEngine.addOnload(function()
    {
    
        jQuery(".pipeText").hide();
    });
    

    Questions 2-6: "What country was your mother/father/maternal grandmother/maternal grandfather/paternal grandmother/paternal grandfather born in?" (Same question type, choices, and Javascript as Question 1, with the exception of "I don't know" as an added choice)

    Choice 1: "I don't know"
    Choice 2: <span class="choiceText">Afghanistan</span><span class="pipeText">Afghan</span>
    All the way to <span class="choiceText">Zimbabwe</span><span class="pipeText">Zimbabwean</span>

    Javascript on Questions 2-6:

    Qualtrics.SurveyEngine.addOnload(function()
    {
        jQuery(".pipeText").hide();
    });
    

    Question 7: "Please use the scale below to indicate how much you agree with the following. Overall, I am..." (Matrix Table: 5-point Likert)

    Choice 1: piped in as selected choice from Question 1
    All the way to: piped in as selected choice from Question 6

    Display logic for the choices piped in from Questions 2-6: Only display if selected choice from Questions 2-6 was not "I don't know."

    Javascript on Question 7 (this time hiding choiceText instead of pipeText):

    Qualtrics.SurveyEngine.addOnload(function()
    {
    jQuery(".choiceText").hide();
    });
    

    What's wrong: when the answer is "I don't know" for Questions 2-6, although the words "I don't know" are not displayed in Question 7, the blank row with all 5 Likert radio buttons is still there. This is why I thought the following code would work:

    Qualtrics.SurveyEngine.addOnload(function()
    {
        if ('${q://QID88~93/ChoiceGroup/SelectedChoices}'= ‘I don't know’)
    {jQuery("#QR~"+this.questionId+"~"+cell).replace(/~/g, "\~").closest("tr").hide();}
        jQuery(".choiceText").hide();
    });
    

    But I'm getting: Error: "Invalid left-hand side in assignment."

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    Your display logic for your Q7 choices must be wrong. It should be:
    if Qx 'I don't know" IS NOT SELECTED where Qx is Q2 through Q6 for each of 2nd through 6th rows. That way there will never be a 'I don't know' row in your matrix and you don't need to hide it with JS.

  • ResearchPsychologist
    edited July 2019

    Oh, I'm sorry: I misspoke. I do have "IS NOT SELECTED." The red circled area is where I chose "I don't know" on one of those previous questions and while the words "I don't know" are not displayed, as you can see, the row still is. See below

  • TomG, you're amazing. Worked like a charm. Thank you very, very much.

  • Additional problem now: when someone chooses the same response to more than one of the questions (participant's own place of birth, place of residence, and place of citizenship, as well as parents' and grandparents' places of birth: all Afghanistan), the piped responses are all the same (Afghan, Afghan, Afghan....) rather than just displaying the piped response once (Afghan). Unfortunately, I cannot use display logic to only show a response when it is not the same as another response (unless I maybe use it for all countries in the list, which would take forever: display if response to the first question is Afghanistan and none of the responses to the remaining questions are Afghanistan, same for Germany, etc.). See below. Suggestions?

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    To do it without JS, you would include a row for all countries in your matrix, then add display logic to each one to display if it was picked in any of the 9 MC questions.

    There are a number of different ways you could do it with JS. My preference would be to do it before you get to the Matrix. Remove the duplicates from the list of selected countries, then set 9 embedded variables so that each one is a unique country from the list or blank. Then pipe those variables in as the row labels of the matrix.

  • Hi, Tom. I wrote the script but it's not working, so it might be incorrect. Either that, or I may misunderstand what you're recommending? As you'll see in the final image, nothing is showing up.

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭

    @ResearchPsychologist said:
    Hi, Tom. I wrote the script but it's not working, so it might be incorrect. Either that, or I may misunderstand what you're recommending? As you'll see in the final image, nothing is showing up.

    Your arguments on setEmbeddedData are backwards. The name of the embedded variable is the first argument, and the value is the second argument.

    I assume you realize that there is nothing in the code to remove the duplicates. You probably want to name your embedded variables country1, country2, etc. because you will want to populate them in a loop after you de-dup.

  • ResearchPsychologist
    edited July 2019

    Thank you so much for the hint! I changed the arguments for the setEmbeddedData. I also changed the names to country1, country2, country3, etc., in both the survey flow and the code. Based on this link https://medium.com/dailyjs/how-to-remove-array-duplicates-in-es6-5daa8789641c and others I looked up, I thought that the code above it created an array and then de-duped and returned the de-duped array, but I guess that is not the case. I'll hunt some more and try more things and see what I can do. Don't know how to de-dupe or do "for loops" yet, but I'll continue trying :smile:

  • ResearchPsychologist
    edited July 2019

    I've spent so many days on this. For the life of me, I cannot figure it out! I tried out my code https://jsconsole.com/ with ["a","b","b","c","d","d"] and console.log instead of Qualtrics.SurveyEngine.setEmbeddedData and it works: I constructed the array, de-duped it with Set, and then put it in a loop that sets the embedded data. I also set the embedded data in the survey flow. But I'm still ending up with nothing in the preview. The green block of embedded data in the survey flow is set before the whole block of questions involving embedded data and the question I'm referencing comes in the middle of the question block. Does that matter? Pretty please, I could use some help!

    UPDATE: I'm certain now that it's something to do with how I set the embedded data and that I've isolated where the problem is occurring, though I still can't solve it. When I take out ALL JavaScript and just use survey flow to create embedded data with the response choices from the prior questions (e.g., country1 = ${q://QID93/ChoiceGroup/SelectedChoices}, etc.) and then pipe in the embedded data into the new question's response choices (e.g., answer choice 1 = ${e://Field/country1}, it's not showing anything in preview for any of the response choices (as shown in the final image above). However, if I create a question where I'm just directly piping in the response choices from the prior questions (e.g., ${q://QID93/ChoiceGroup/SelectedChoices}, instead of piping in embedded data and setting the embedded data, e.g., ${e://Field/country1}, as the response choices from the prior questions), it works. However, I cannot do the question this way as I am unable to de-dupe the piped in response choices. (So instead, as TomG advised, I have to construct an array, de-dupe, and set the embedded data from a loop and pipe it back in. Or is there another way?)

  • TomG
    TomG Raleigh, NC Wizard ✭✭✭✭✭
    edited August 2019

    Check these things in order...

    1. Is your JavaScript attached to the Matrix question? If so, that is your problem. You can't set and pipe an embedded variable on the same page (the replacement happens on the Qualtrics server before the page is sent to the browser). The way it is currently written it has to be on a page after your last country question and before your matrix question.

    2. Why are you assigning values to country1, etc. in an Embedded Data block? Those assignments are happening in the JS. If you want country1, etc. in your response data leave the value blank (e.g. country1 = ). Also, that block has to be before the block with your JS.

    Edit: Here is a working example that uses a page inbetween with a descriptive text question where the addOnReady function runs the script and clicks the Next Button.
    https://marketinview.ca1.qualtrics.com/jfe/preview/SV_aW2dkZEPWPvWThr?Q_SurveyVersionID=current&Q_CHL=preview