Hi, As I was looking for it and didn’t find it, I wanted to share with you the code that was written for me, so everyone can enjoy it and give back to the community.
This code should be copied to the JS of a specific question where you have a list of items, and you want customers to see your list of options sorted in all languages alphabetically.
This code is applying the following rules:
-
Fixed choices – you should provide all the choices you do not want to be sorted and they will appear *In the order provided AT THE END OF THE SORTED LIST*… here are 3 scenarios:
- One choice only – for example “other”, just add it for each language, as in the following 'EN': 'Other'
-
List of some choices – here you should provide the words in the following format: 'ES': ['Perro', 'Gato', 'Niño', 'Bebé', 'Globo', 'Otro']
-
All the choices of the question – You will have to do it for languages that their sorting rules are complicated in Java Script. We tested AR, HE, TH, SR, RU, UK, VI, KO, ES, PT-BR, TR. All of them are working great. ZH-S and JA doesn’t and need to use this all choices as fixed. Please make sure that for the JA and ZH-S localization you ask it against the English + ask them to provide next to it the order it should be in. It will help you then sort in excel by the numbers and put it into the list following format should be used: 'JA': ['XXX', 'XXX', 'XXX']
-
Rest of the choices – the rest of the choices that are not in fixed, will be sorted according to the language rules, followed first by the check if the choice starts with an English word. For example: IT・ネットワーク(テクニカルサポート)- The word IT is in English, so this choice will appear first. or like in Russian 2 words are sorted as first based on English (See image at end of point 4)
-
If an option is provided with text entry box, it will always be the last choice presented (for example “other, please specify”)
-
The code will work on all list options questions, including using columns.
Here is an example of all the options in Russian

So now the code itself and I left an example in JA and EN for the fixedchoices:
Qualtrics.SurveyEngine.addOnReady(function () {
var $this = jQuery(this.questionContainer);
var fixedChoices = {
'EN': 'Other (Please specify)',
'ES': '',
'PT-BR': '',
'SR': '',
'VI': '',
'TR': '',
'RU': '',
'UK': '',
'HE': '',
'AR': '',
'TH': '',
'KO': '',
'JA': ['IT・ネットワーク(テクニカルサポート)', 'ウェブ、モバイル、ソフトウェア開発']'],
'ZH-S': ''
};
var sortChoices = function () {
var lang = jQuery("#Q_lang").length > 0 ? jQuery("#Q_lang").val() : '${e://Field/Q_Language}';
var $el = jQuery(".ChoiceStructure", $this);
if ($el.is("table")) {
let targetElement = $el[0];
var tds = Array.from(targetElement.querySelectorAll('td.ControlContainer, td.LabelContainer'));
var sortedTds = [];
for (var i = 0; i < tds.length; i += 2) {
sortedTds.push({ control: tds[i], label: tds[i + 1] });
}
// Sort choices
sortedTds.sort(function (a, b) {
if (jQuery(".LabelWrapper .InputText", jQuery(a.label)).length > 0) {
return 1;
}
if (jQuery(".LabelWrapper .InputText", jQuery(b.label)).length > 0) {
return -1;
}
var textA = a.label.querySelector('span').textContent.trim();
var textB = b.label.querySelector('span').textContent.trim();
if (Array.isArray(fixedChoices[lang])) {
var indexA = fixedChoices[lang].indexOf(textA);
var indexB = fixedChoices[lang].indexOf(textB);
if (indexA !== -1 && indexB !== -1) {
return indexA - indexB;
}
}
if (/^[A-Za-z]/.test(textA) && !/^[A-Za-z]/.test(textB)) {
return -1;
}
if (!/^[A-Za-z]/.test(textA) && /^[A-Za-z]/.test(textB)) {
return 1;
}
return textA.localeCompare(textB, lang, { sensitivity: 'base', ignorePunctuation: true, numeric: true });
});
let totalCols = jQuery("tr:first .ControlContainer", $el).length;
let curTdIndx = 0;
for (let col = 0; col < totalCols; col++) {
for (let i = 0; i < Math.ceil(sortedTds.length / totalCols); i++) {
let row, isAddRow = false;
if (col == 0) {
row = document.createElement('tr');
row.className = (i % 2 === 0 ? 'reg' : 'alt') + ' cust-row';
isAddRow = true;
} else {
row = jQuery("tr.cust-row:eq(" + i + ")", $el);
}
let pair = curTdIndx <= (sortedTds.length - 1) ? sortedTds[curTdIndx] : { control: '<td> </td>', label: '<td> </td>' };
row.append(pair.control, pair.label);
isAddRow ? targetElement.tBodies[0].append(row) : "";
curTdIndx++;
}
}
jQuery("tr:not(.cust-row)", $el).remove();
} else {
let targetElement = $el[0];
let opChoices = targetElement.children;
opChoices = Array.prototype.slice.call(opChoices);
// Sort choices
opChoices.sort(function (a, b) {
if (jQuery(".LabelWrapper .InputText", jQuery(a)).length > 0) {
return 1;
}
if (jQuery(".LabelWrapper .InputText", jQuery(b)).length > 0) {
return -1;
}
var textA = a.textContent.trim();
var textB = b.textContent.trim();
if (Array.isArray(fixedChoices[lang])) {
var indexA = fixedChoices[lang].indexOf(textA);
var indexB = fixedChoices[lang].indexOf(textB);
if (indexA !== -1 && indexB !== -1) {
return indexA - indexB;
}
}
if (/^[A-Za-z]/.test(textA) && !/^[A-Za-z]/.test(textB)) {
return -1;
}
if (!/^[A-Za-z]/.test(textA) && /^[A-Za-z]/.test(textB)) {
return 1;
}
return textA.localeCompare(textB, lang, { sensitivity: 'base', ignorePunctuation: true, numeric: true });
});
for (let i = 0; i < opChoices.length; i++) {
targetElement.appendChild(opChoices[i]);
}
}
}
sortChoices();
});