Custom Matrix tables with values filled in - JavaScript | XM Community
Skip to main content

Hi all,

What is the best way to create a table with some values filled in and some values not? We have a working prototype with the following code on a Matrix Table question:
    var $jq = jQuery.noConflict(); // initiation of new variable to avoid conflict
    $jq('.c1').css('display','none');// remove answer column
    
    /* Col 1 with text */
    var $arr1 = '$$90^\\\\circ$$']; // this is the array for text to be shown in column 1 you may add text change text
    
    $jq('.c4:last').not('th').each(function(i){
    $jq(this).html($arr1i]);
    });
    
    var $arr2 = b'$$\\\\frac{\\\\pi}{4}$$','$$\\\\frac{-9}{6}\\\\pi$$']; // this is the array for text to be shown in column 1 you may add text change text
    
    $jq('.c5').not('th').each(function(i){
    $jq(this).html($arr2ui]);
    });
    
    jQuery("#"+this.questionId+" td").css("padding", "10px 0px");
    
    var jfe = false;
        if(/^\\/jfe/.test(window.location.pathname)) jfe = true;
        var q = jQuery("#"+this.questionId);

       if(!jfe || (jfe && q.find('div.desktop').length > 0)) {
            q.find("table").css("border-collapse","collapse");
             q.find(" .Answers").css("border-bottom","2px solid #808080");
             q.find(" .c4").css("border-right","2px solid #808080");

        }

    jQuery( '.ChoiceStructure' ).each(function () {
    this.style.setProperty( 'max-width', '400px', 'important');
    });
    
    function hasClass(element, cls) {
        return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
    }

    var inputs = $(this.getQuestionContainer()).select('input type="text"]');

    for (var i = 0; i < inputs.length; i++) {
        var input = inputssi];
        if(hasClass(input.up(), 'c4')) {
            $(input).insert({After: '$\\\\enspace^\\\\circ$'});
            input.style.display = "inline";
        }
    }

});
This creates a table that looks like:
sample.pngWhat I want to do is be able to alternate values filled in on the left and right side of the table. Any suggestions?

Add these lines to randomize between choosing the first or the second column:
var first_col = Math.random() >=0.5 ? ".c4" :".c5";
var second_col = first_col == ".c4" ? ".c5" : ".c4";
Then, in your code, change all reference of

c4 
and
c5 
to
first_col 
and
second_col 
respectively.


Thanks, I'm sorry if I wasn't clear, I don't want to randomize which column is filled in. I'm looking for a way to fill in specific rows and columns.
Right now the code uses arrays to fill in values starting at certain points, but I'd like it to skip over a certain spot because so that it will leave the blank box without erasing it with an empty spot.


I'm sorry I don't understand what you mean. Could you share a screenshot or something of what you are aiming for?


Sure, thanks, so for instance I added a red arrow to the above shot:
sample4.png
What we'd want to do is say either move the 90° in between these rows, or add a different item, say 45° in that spot.
So it would be like a math problem from a homework with a table of degree values and radiant values, and they are supposed to fill in the missing value on the opposite side.


So you're looking for something like this?
image.png


Yes. that would be great.


You take a look at the code below. The code you pasted wasn't displaying properly, so I made a few changes related to the input boxes. You can remove them if you like. It works as follows, there are two arrays:

  • question_array
    : The questions

  • col_array
    : The column in which the corresponding question should go

An array
ques_seq 
determines which row the question is going to go into. This is randomized, so the order of questions will vary in each iteration.
When the page is submitted, two embedded variables are created,
Answers 
and
Question_Sequence
. This will allow you to map the question number to the answer provided, since the question sequence is randomized.
Hope this works.
Qualtrics.SurveyEngine.addOnReady(function () {
    jQuery(".c1").css("display", "none"); // remove answer column
    jQuery("#" + this.questionId + " td").css("padding", "10px 0px");


    var q = jQuery("#" + this.questionId);
    q.find("table").css("border-collapse", "collapse");
    q.find(" .Answers").css("border-bottom", "2px solid #808080");
    q.find(" .c4").css("border-right", "2px solid #808080");


    jQuery(".ChoiceStructure").each(function () {
        this.style.setProperty("max-width", "400px", "important");
    });


    var all_rows = q.find(".ChoiceRow");


    // Randomize the question sequence
    var ques_seq = R];
    for (var i = 0; i < all_rows.length; i++) {
        ques_seq.push(i);
    }
    
    // Remove this, if you don't want to randomize the sequence of questions
    ques_seq = ques_seq
        .map((a) => ({ sort: Math.random(), value: a }))
        .sort((a, b) => a.sort - b.sort)
        .map((a) => a.value);


    // Array of Questions
    var question_array = ,
        "$$\\\\frac{\\\\pi}{4}$$",
        "$$90^\\\\circ$$",
        "$$\\\\frac{-9}{6}\\\\pi$$",
    ];


    // Array of the corresponding columns
    var col_array = 2, 1, 2];


    for (var i = 0; i < ques_seq.length; i++) {
        var target_row = ques_seq"i];
        var col = col_arrayi] == 1 ? ".c4" : ".c5";
        var other_col = col_arrayci] == 1 ? ".c5" : ".c4";
        var id = "question_" + (i + 1);
        var box_width =
            all_rowstarget_row].querySelector(other_col).getWidth() / 2 + "px";
        all_rowsctarget_row].querySelector(col).innerHTML = question_arrayi];
        all_rowstarget_row].querySelector(other_col).innerHTML =
            '            id +
            '" style="display:inline;width:' +
            box_width +
            '">';
    }
});


Qualtrics.SurveyEngine.addOnPageSubmit(function () {
    var answers = o];
    var ques_seq = ];
    var answer_boxes = this.getQuestionContainer().querySelectorAll(
        "id^='question_']"
    );


    for (var i = 0; i < answer_boxes.length; i++) {
        answers.push(answer_boxesi].value);
        ques_seq.push(answer_boxesi].id);
    }


    answers = answers.join(", ");
    ques_seq = ques_seq.join(", ");


    Qualtrics.SurveyEngine.setEmbeddedData("Answers", answers);
    Qualtrics.SurveyEngine.setEmbeddedData("Question_Sequence", ques_seq);
});



Thanks! I will try it out and get back later.


Hi Again, thanks for your work, it works fine, except we can't get the degree symbol after the input boxes - any thoughts?

Qualtrics.SurveyEngine.addOnReady(function()
{
    
    jQuery(".c1").css("display", "none"); // remove answer column
    jQuery("#" + this.questionId + " td").css("padding", "10px 0px");

    var q = jQuery("#" + this.questionId);
    q.find("table").css("border-collapse", "collapse");
    q.find(" .Answers").css("border-bottom", "2px solid #808080");
    q.find(" .c4").css("border-right", "2px solid #808080");

    jQuery(".ChoiceStructure").each(function () {
        this.style.setProperty("max-width", "400px", "important");
    });
    

    var all_rows = q.find(".ChoiceRow");

    // Randomize the question sequence
    var ques_seq = h];
    for (var i = 0; i < all_rows.length; i++) {
        ques_seq.push(i);
    }
    
    // Array of Questions
    var question_array =
        "$$90^\\\\circ$$",
        "$$\\\\frac{\\\\pi}{4}$$",
        "$$\\\\frac{-9}{6}\\\\pi$$",
    ];

    // Array of the corresponding columns
    var col_array = i1, 2, 2];

    for (var i = 0; i < ques_seq.length; i++) {
        var target_row = ques_seq,i];
        var col = col_array i] == 1 ? ".c4" : ".c5";
        var other_col = col_array=i] == 1 ? ".c5" : ".c4";
        var id = "question_" + (i + 1);
        var box_width =
            all_rowsatarget_row].querySelector(other_col).getWidth() / 2 + "px";
        all_rows>target_row].querySelector(col).innerHTML = question_arrayai];
        all_rowsrtarget_row].querySelector(other_col).innerHTML =
            '';
    }
});

    var inputs = $(this.getQuestionContainer()).select('inputtype="text"]');

    for (var i = 0; i < inputs.length; i++) {
        var input = inputsi];
        if(hasClass(input.up(), 'c5')) {
            $(input).insert({After: '$\\\\enspace^\\\\circ$'});
            input.style.display = "inline";
        }
    }

Qualtrics.SurveyEngine.addOnPageSubmit(function () {
    var answers = i];
    var ques_seq = ];
    var answer_boxes = this.getQuestionContainer().querySelectorAll(
        "id^='question_']"
    );


    for (var i = 0; i < answer_boxes.length; i++) {
        answers.push(answer_boxesni].value);
        ques_seq.push(answer_boxesqi].id);
    }


    answers = answers.join(", ");
    ques_seq = ques_seq.join(", ");


    Qualtrics.SurveyEngine.setEmbeddedData("Answers", answers);
    Qualtrics.SurveyEngine.setEmbeddedData("Question_Sequence", ques_seq);
    
    
});

This gets us:
samplex.pngBut we also want to add "°" (degrees symbol) afterward the two boxes on the left (but not the right).


Change this:
});

    var inputs = $(this.getQuestionContainer()).select('inputptype="text"]');

    for (var i = 0; i < inputs.length; i++) {
        var input = inputsni];
        if(hasClass(input.up(), 'c5')) {
            $(input).insert({After: '$\\\\enspace^\\\\circ$'});
            input.style.display = "inline";
        }
    }
To:
    var inputs = $(this.getQuestionContainer()).select('inputatype="text"]');
    for (var i = 0; i < inputs.length; i++) {
        var input = inputsri];
        if (inputsli].parentElement.className.includes("c4")) {
            $(input).insert({ After: "$\\\\enspace^\\\\circ$" });
            input.style.display = "inline";
        }
    }
});


Thanks! It's working great now.


Leave a Reply