How to use JS and HTML to randomise words across 24 MCQ's plus use piped text from these responses? | XM Community
Skip to main content

I am very new to coding, particularly within Qualtrics. I have tried everything to build a specific survey, including the support forums, but to no avail. Here is what I am trying to achieve:
I have a memory task that I am trying to replicate in Qualtrics as I have moved my study to online data collection. Basically, I have 24 MCQ questions that each have only one response option, to allow a text response. This is to enable piped text, from the text entry field below, to appear in a self-rating block at the end of the survey:
Picture2.png
The survey is split into three blocks of cue words where 24 cue words are presented only once each across the whole study (24 cue word questions in total across whole survey). Each block begins with the cue word question plus seven slider scale questions, to allow various ratings of the memory previously entered into the MCQ text entry field. After all 24 words, plus slider scale questions, have been answered, participants are then asked to rate each memory that they entered for each cue word question (from the text entry field of the MCQ questions). I am using two fields for the piped text to display back to participants, the MCQ (text field) response to each cue word as well as the corresponding cue word that they saw for each cue question text.
I was thinking the following structure but not sure if possible with JS code and word randomisation (with no cue word repeats) across all 24 blocks for the 1st question (MCQ) only:
Practice block – only 4 sets of the MCQ plus slider questions
Trial block 1 - 1 MCQ cue word (randomised, no repeats) plus 7 slider questions – repeated 6 times in total
Trial block 2 - 1 MCQ cue word (randomised, no repeats) plus 7 slider questions – repeated 6 times in total
Trial block 3 - 1 MCQ cue word (randomised, no repeats) plus 7 slider questions – repeated 12 times in total but each cue word question instructions alternate from ‘Please retrieve a SPECIFIC memory’ to ‘Please retrieve a CATEGORICAL memory’
What I need is for the 24 cue words to be randomised across all 24 cue questions across the whole survey, but I cannot figure out a way to achieve this if I keep the three separate blocks.
I did consider one set of grouped questions (the cue word plus seven rating scale questions) then repeated 24 times using loop and merge, but each block has different instructions, and I cannot get the piped text display block at the end to work using this layout.
I think it might be easier to have all 24 questions listed separately, as this won’t take long to copy, but I need a JS code that I could use that would randomise the 24 cue words across all 24 questions, across the 3 trial blocks. My added complication is that the 24 cue words are from three categories based on word valence; pos (e.g., happy), neg (e.g., lonely) and neutral (e.g., library) and the valence of the word will alternate so that it is always pos, then neg, then neu order. If I can find a suitable JS code for the randomisation across all 24 cue words, across all three blocks, then I could separate the cue words so I have one pos JS cue word list, plus another for neg and another for neu words.
I am using the JS code, plus HTML question code, below that I found from a support forum (but this is for loop and merge and I’m not sure that this is suitable for my survey design). So far, I have got this to work for a practice block (with 4 sets of the MCQ plus 7 rating questions):
HTML code for question text:
Please retrieve a span id memory to the cue word below:


JS code for alternating instruction block (Specific or Categorical):
Picture3.png
This partially works for randomly displaying a cue word from one question but not from a loop and merge randomised cue word set-up. However, I cannot get the piped text to work so that participants can see the cue word that they were originally, randomly presented with. Instead, it is either blank or displays this ‘You can leave this empty also’. Below is a screenshot of the self-rating question with two fields of piped text but only the participant text entry field working fine:
Picture1.png
Another issue is that I cannot get the embedded data to work so that I can export the list of typed memories plus the cue word that they were presented with for each question - this is crucial to my study.
What I need to know most of all is the easiest, most effective structure of my survey (with or without the blocks and loop and merge) and then help with figuring out the code to enable this to work.
For the alternating instructions block, I also need to have the cue word and memory type in bold within the question HTML. I have figured out the code for the last word (cue word) but not for the memory type as being mid-sentence complicates matters. I tried this but it won’t work with JS as I’m not sure what I should put where I’ve added “random1” – I’ve even tried span id in front of this but it still won’t work:
Please retrieve a “random1” memory to the cue word below:


Picture4.png
I hope I have sufficiently explained my current difficulties. I would be super grateful if anyone could help me as I desperately need to get my PhD study up and running.




Hi SamJ,
these are a lot of questions within one post 🙂
my idea for your first requirement - distirbuting the items randomly in three blocks - would be:

  1. create an embedded data field selectedCueWordsRecodes in the survey flow. We will use this to store the already selected cue words

  2. create 3 questions with all your cue words as answer options

  3. allow multiple answers

  4. make sure that the cue words have all the same recodes

  5. create 3 loop&merge blocks

  6. base each loop&merge block on one of the multiple choice question

Java scripts

add this script to the first multiple choice question
function getRandom(arr, n) {
    var result = new Array(n),
        len = arr.length,
        taken = new Array(len);
    if (n > len)
        throw new RangeError("getRandom: more elements taken than available");
    while (n--) {
        var x = Math.floor(Math.random() * len);
        resulten] = arrx in taken ? taken]x] : x];
        taken[x] = --len in taken ? takenelen] : len;
    }
    return result;
}




Qualtrics.SurveyEngine.addOnload(function()
{
let allChoices = this.getChoices() // 

console.log(allChoices)

for(let i =0;i
this.setChoiceValue(allChoicesbi],0)
}

for(let i =0;i
this.setChoiceValue(allChoicesbi],0)
}

let choicesSelected = getRandom(allChoices,6) // 6: number of cue words to be selected

for(let i =0;i
this.setChoiceValue(choicesSelectedti],1)
}


});




Qualtrics.SurveyEngine.addOnPageSubmit(function()
{

let selectedChoices = this.getSelectedChoices()
let  selectedCueWordsRecodes = new Array;

for(let i = 0; i
selectedCueWordsRecodes.push(Number(selectedChoicessi]))
}

 
Qualtrics.SurveyEngine.setEmbeddedData("selectedCueWordsRecodes", selectedCueWordsRecodes.join(','));



});

add the below script to the second and third multiple choice question:
function getRandom(arr, n) {
    var result = new Array(n),
        len = arr.length,
        taken = new Array(len);
    if (n > len)
        throw new RangeError("getRandom: more elements taken than available");
    while (n--) {
        var x = Math.floor(Math.random() * len);
        result n] = arrMx in taken ? takendx] : x];
        takenx] = --len in taken ? takennlen] : len;
    }
    return result;
}




Qualtrics.SurveyEngine.addOnload(function()
{
let availableChoices = this.getChoices() // 
let availableChoicesRecode = new Array;
let eligibleChoicesRecode = new Array;



let selectedCueWordsRecodes = "${e://Field/selectedCueWordsRecodes}".split(',')



for(let i =0;i
availableChoicesRecode.push(Number(this.getChoiceRecodeValue(availableChoicesai])))
}

for(let i =0;i
this.setChoiceValueByRecodeValue(availableChoicesRecodeii],0)
}

for(let i=0; i
if(!selectedCueWordsRecodes.include(availableChoicesRecode)i])){
eligibleChoicesRecode.push(availableChoicesRecodeci])    
   
}

}

let selectChoices = getRandom(eligibleChoicesRecode,6) // 6: number of cue words to be selected change this to 12 for the third block

for(let i =0;i
this.setChoiceValue(selectChoices ;i],1)
}


});




Qualtrics.SurveyEngine.addOnPageSubmit(function()
{

let selectedChoices = this.getSelectedChoices()
let  selectedCueWordsRecodes = "${e://Field/selectedCueWordsRecodes}".split(',')


for(let i = 0; i
selectedCueWordsRecodes.push(Number(selectedChoicesCi]))
}

 
Qualtrics.SurveyEngine.setEmbeddedData("selectedCueWordsRecodes", selectedCueWordsRecodes.join(','));



});
The next things you need to look into are:
  1. find a solution how you make sure that you pick and equal number of positive, negative and neutral cue words

  2. my first idea would be to create 3 arrays which hold the respective answer precodes for positive, negative and neutral cue words in your javascript

  3. here you might need to have three additional embedded data fields which store the used precodes for the positive, negative and neutral codes you have already used something like selectedCueWordsRecodesPositive, selectedCueWordsRecodesNegative, selectedCueWordsRecodesNeutral

  4. find a way how to manipulate the order within a loop and merge block

  5. the first step would be to bring the selected cuewords from the selection blocks in the order you want and store them in embedded data fields orderBlock1, orderBlock2 and orderBlock3

I am aware that this doesn't answer your questions completely but I hope it will help you to start off. My ball park effort estimation for realizing this setup would be at least 3 to 4 days :-)

Best regards

Rudi


Hi Rudi,
Sorry, you are absolutely right - that was a lot to ask in one post!
Thank you so much for taking the time to offer me so much advice, this is really helpful as I never would have figured that code out. I will follow your suggestions and see how I get on. :-)
Best wishes,
SamJ


Hey @SamJ,

just wondered how your setup is going? HAve you gotten on with your survey?

Best regards

Rudi


Leave a Reply