Drawing words without replacement from an Embedded Data list over loops | XM Community
Skip to main content
Question

Drawing words without replacement from an Embedded Data list over loops

  • 18 July 2024
  • 2 replies
  • 15 views

Hello,

My question is: Why the JS code does not work to pick and/or display the drawn word in the question?

With my current script, the question container appears but empty, it looks like there is no communication between the script and the embedded data field… I don’t know if the issue comes from the words writing in the embedded fields, or else.

 

My goal is to draw one word randomly without replacement at each loop from an embedded list of words based on the initialWordList:

The wordlist field is equal to initialWordList – drawnList, so at the beginning the wordlist contains all the words of initialWordList, and supposed to be emptied over loops.

The drawnList field is supposed to store all the drawn words picked at each loop in wordList. So at the beginning the drawnList is empty, and supposed to be filled over loops.

 

FYI: the wordlist and the drawnList are supposed to be kept updated within and between participants, until the wordlist is empty and the drawnList is full. Then both lists are reset (wordlist=initialWordList and drawnList=” ”) to restart. For the experiment, the list will contain 280 words.

 

The picked word is supposed to be displayed in a question container as follows:

Here is the script, I think the issue is in part 1 or/and 2, maybe 4:

Qualtrics.SurveyEngine.addOnload(function() {   

 
// PART 1: Set up initial conditions for Embedded Data    
    // Get the initial word list and drawn word
    var initialWordList = "${e://Field/initialWordList}".split(',');  
    var drawnList = "${e://Field/drawnList}".split(',');  
    

    // Filter out the drawn word from the initial word list
    var wordList = initialWordList.filter(function(word) {  

        return word.trim() !== drawnList.trim(); 

    });

    
    // Set the updated word list to the wordList embedded data field
    Qualtrics.SurveyEngine.setEmbeddedData('wordList', wordList.join(','));

    var wordList = "${e://Field/wordList}".split(',');
 

  

// PART 2: Function to draw a word randomly without replacement 


    function drawWordWithoutReplacement(wordList) {
           // Check if the wordList is empty
        if (wordList.length === 0) {
            // If it is empty, reset the list to the initial state 
            wordList = initialWordList.slice();

            drawnList = ];

        }

        // Randomly select an index
        var index = Math.floor(Math.random() * wordList.length);
        // Remove and get the selected word from the wordList
        var drawnWord = wordList.splice(index, 1)/0]; 
        // Add the selected word to the drawnList list
        drawnList.push(drawnWord); 
        // Return the selected word
        return drawnWord;

    }

    
    // Draw a word from the list
    var drawnWord = drawWordWithoutReplacement(wordList); 

});


Qualtrics.SurveyEngine.addOnload(function() {

    
// PART 3 : Set up the appearance of the text and container

    // Hide the text for the question (this is ok, necessary because the container at the top of the bloc)
    this.getQuestionContainer().style.display = 'none';
    
    // Get the current question's HTML content
    var textGraphicHTML = this.getQuestionTextContainer().innerHTML;

    // Create a fixed container
    var fixedContainer = document.createElement('div');

    fixedContainer.id = 'fixedTextContainer';

    fixedContainer.style.position = 'fixed';

    fixedContainer.style.top = '0';

    fixedContainer.style.width = '100%';

    fixedContainer.style.backgroundColor = 'white';

    fixedContainer.style.zIndex = '1000';

    fixedContainer.style.padding = '10px';

    fixedContainer.style.boxShadow = '0 2px 5px rgba(0,0,0,0.1)';

    fixedContainer.innerHTML = textGraphicHTML;

    
    // Insert the fixed container into the body
    document.body.insertBefore(fixedContainer, document.body.firstChild);

    // Adjust the body padding to prevent content overlap
    document.body.style.paddingTop = fixedContainer.offsetHeight + 'px';
    
    // Display the drawn word in the question
    var container = document.getElementById('randomWordContainer');

    if (container) {

        container.innerHTML = drawnWord;

    }

    

// Part 4: Update lists

// Retrieve the current state of the word list and drawn words from embedded data
    var wordList = "${e://Field/wordList}".split(',');

    var drawnList = "${e://Field/wordList}".split(',');

    

// Set the updated word list to the wordList embedded data field
    Qualtrics.SurveyEngine.setEmbeddedData('wordList', wordList.join(','));

    Qualtrics.SurveyEngine.setEmbeddedData('drawnList', drawnWord.join(','));

    
});

 

Thank you in advance !

Yen

2 replies

Userlevel 5
Badge +17

@Yentl Few remarks… 

  • Your current code attempts to filter initialWordList with drawnList but drawnList is an array, so wordList will always be empty. You need to filter initialWordList to remove words already present in drawnList.

  • Ensure you update the wordList and drawnList embedded fields correctly after drawing a word.

  • Make sure the drawn word is correctly displayed in the question container.

  • Ensure the wordList and drawnList are reset appropriately when wordList becomes empty.

Try this: 

Qualtrics.SurveyEngine.addOnload(function() {
// PART 1: Set up initial conditions for Embedded Data
// Get the initial word list and drawn word list
var initialWordList = "${e://Field/initialWordList}".split(',');
var drawnList = "${e://Field/drawnList}".split(',');

// Filter out the drawn words from the initial word list
var wordList = initialWordList.filter(function(word) {
return drawnList.indexOf(word.trim()) === -1;
});

// If the wordList is empty, reset it to the initial state
if (wordList.length === 0) {
wordList = initialWordList.slice();
drawnList = [];
}

// PART 2: Function to draw a word randomly without replacement
function drawWordWithoutReplacement(wordList) {
// Randomly select an index
var index = Math.floor(Math.random() * wordList.length);
// Remove and get the selected word from the wordList
var drawnWord = wordList.splice(index, 1)[0];
// Add the selected word to the drawnList list
drawnList.push(drawnWord);
// Return the selected word
return drawnWord;
}

// Draw a word from the list
var drawnWord = drawWordWithoutReplacement(wordList);

// PART 3: Set up the appearance of the text and container
// Hide the text for the question
this.getQuestionContainer().style.display = 'none';

// Get the current question's HTML content
var textGraphicHTML = this.getQuestionTextContainer().innerHTML;

// Create a fixed container
var fixedContainer = document.createElement('div');
fixedContainer.id = 'fixedTextContainer';
fixedContainer.style.position = 'fixed';
fixedContainer.style.top = '0';
fixedContainer.style.width = '100%';
fixedContainer.style.backgroundColor = 'white';
fixedContainer.style.zIndex = '1000';
fixedContainer.style.padding = '10px';
fixedContainer.style.boxShadow = '0 2px 5px rgba(0,0,0,0.1)';
fixedContainer.innerHTML = textGraphicHTML;

// Insert the fixed container into the body
document.body.insertBefore(fixedContainer, document.body.firstChild);

// Adjust the body padding to prevent content overlap
document.body.style.paddingTop = fixedContainer.offsetHeight + 'px';

// Display the drawn word in the question container
var container = document.getElementById('randomWordContainer');
if (container) {
container.innerHTML = drawnWord;
}

// PART 4: Update lists
// Set the updated word list to the wordList embedded data field
Qualtrics.SurveyEngine.setEmbeddedData('wordList', wordList.join(','));
// Set the updated drawn list to the drawnList embedded data field
Qualtrics.SurveyEngine.setEmbeddedData('drawnList', drawnList.join(','));
});

 

Thank you so much for your quick reply ! I’ll try it and come back to you with the results !

Leave a Reply