Side by Side dropdown values inaccessible via JavaScript in New Survey Taking Experience | Experience Community
Skip to main content
Question

Side by Side dropdown values inaccessible via JavaScript in New Survey Taking Experience

  • June 24, 2026
  • 1 reply
  • 1 view

Hi all,

 

I am trying to use JavaScript to read the selected values from a manually built Side by Side question with three dropdown columns (Month, Day, Year) in order to calculate a decimal-year age and write it to embedded data fields using setJSEmbeddedData.

 

I have confirmed the following are all working correctly:

 

• JavaScript is executing

• addOnload and addOnReady are both firing

• Qualtrics.SurveyEngine.setJSEmbeddedData is writing to embedded data correctly

• The Survey Flow has the three fields declared with the _js prefix

• The Gratitude block is in place so the DOB question is not on the final page

 

The problem is that I cannot read the dropdown values from the Side by Side question. I have tried:

• document.getElementsByName(‘QR~’+qid+’#1~1’)[0] — returns undefined

• document.querySelectorAll(‘select’) — returns zero elements

• document.querySelectorAll(’#’+qid+’ select’) — returns zero elements

• document.getElementById(qid) — returns null

• document.body.innerHTML — shows question text is present but no select elements visible in the DOM when addOnReady fires

 

My question is: what is the correct method for reading the selected values from a Side by Side dropdown question under the New Survey Taking Experience?

 

Any help would be greatly appreciated. Thank you.

1 reply

vgayraud
QPN Level 7 ●●●●●●●
Forum|alt.badge.img+65
  • QPN Level 7 ●●●●●●●
  • June 25, 2026

Hi,

The SBS DOM changed between the two experiences:

  • Container — Classic: #{qid}. New: #question-{qid}. That's why getElementById(qid) was null.
  • Dropdowns aren't <select> — they're now ARIA comboboxes (div + ul/li), so querySelectorAll('select') finds nothing. The value lives in the <li class="menu-item selected">.
  • Naming — Classic used QR~{qid}#{col}~{row}. New uses ids: sbs-dropdown-{qid}-{statement}-{column} per cell. The old getElementsByName('QR~...') matches nothing.

The attached script reads selections from this structure, scanning every sbs-dropdown combobox so it handles any number of dropdown columns. Add it to your question and check your console log to get the information you need to adapt your script.

Qualtrics.SurveyEngine.addOnReady(function () {
var qid = this.questionId;
var container = document.getElementById('question-' + qid);
if (!container) {
console.warn('No container for', qid);
return;
}

// READ ALL DROPDOWN SELECTIONS
// Returns array of { id, statement, column, answer, label }
// Scans every sbs-dropdown combobox in the question, regardless of column count.
function readDropdowns() {
var results = [];
var buttons = container.querySelectorAll('[id^="sbs-dropdown-' + qid + '-"][role="combobox"]');

for (var i = 0; i < buttons.length; i++) {
var btn = buttons[i];

// id format: sbs-dropdown-{qid}-{statement}-{column}
var idMatch = btn.id.match(new RegExp('^sbs-dropdown-' + qid + '-(\\d+)-(\\d+)$'));
if (!idMatch) continue;
var statement = idMatch[1];
var column = idMatch[2];

// selected option lives in the associated listbox
var listId = btn.getAttribute('aria-controls');
var sel = listId ? document.querySelector('#' + listId + ' .menu-item.selected') : null;
if (!sel) continue;

// answer index = trailing segment of li id; empty = "Select one" (unanswered)
var ansMatch = sel.id.match(/-(\d*)$/);
var answer = ansMatch ? ansMatch[1] : '';
if (answer === '') continue;

var labelEl = sel.querySelector('.rich-text');
var label = labelEl ? labelEl.textContent.trim() : sel.textContent.trim();

results.push({
id: btn.id,
statement: statement,
column: column,
answer: answer,
label: label
});
}

return results;
}

function logRows() {
var rows = readDropdowns();
console.group('SBS dropdown selections — ' + qid);
if (!rows.length) {
console.log('(no dropdown selections)');
} else {
for (var i = 0; i < rows.length; i++) {
console.log(
rows[i].id,
'| statement ' + rows[i].statement,
'| column ' + rows[i].column,
'| answer ' + rows[i].answer,
'| "' + rows[i].label + '"'
);
}
}
console.groupEnd();
}

// defer so React applies the .selected class before we read
function dump() {
setTimeout(logRows, 50);
}

// initial state + live updates
logRows();
container.addEventListener('click', dump);
container.addEventListener('change', dump);
});