Select2 loads JSON but doesn't search | XM Community
Skip to main content

Hi everyone.

I’ve successfully created a Multiple choice question using Select2 to render options via an online JSON file and works fine…..initially.  But when try to keyword search, it doesn’t seem to limit the results - just blips/refreshes the list and displays everything again.

It’s working great for embedded data on a duplicate question, but the external JSON referenced data is buggy.

The JSON file is saved to Qualtrics file system for testing initially - not sure if that should make a difference., The final form will source the data from a different domain.

Here’s my code:

Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/

jQuery('#' + this.questionId + ' select').select2({
ajax: {
url: 'https://submit.dese.gov.au/ControlPanel/File.php?F=F_LbC2C0OmXT7JG1k',
dataType: 'json'
},
placeholder: 'Search for provider name or code...',
width: '100%',
cache: false
});
});

And here’s the result:

https://submit.dese.gov.au/jfe/preview/previewId/74d22d76-4b9f-4e35-8f53-4c1bc0f6a2cf/SV_ddjSimEpD4qN8HA?Q_CHL=preview&Q_SurveyVersionID=current

What am I missing? is it the query string in the source URL?

According to the select2 documentation, I think what you are running into is:

"Select2 expects results from the remote endpoint to be filtered on the server side. See this comment for an explanation of why this implementation choice was made. If server-side filtering is not possible, you may be interested in using Select2's support for data arrays instead."

Which links to this GitHub issue discussion describing the issue you are running into with the filtering.

So since server side filtering is not happening, the data can be preloaded. The below is working for me using your file:

Qualtrics.SurveyEngine.addOnReady(function()
{
/*Place your JavaScript here to run when the page is fully displayed*/
let cachedData = [];

jQuery('#' + this.questionId + ' select').select2({
ajax: {
transport: function (params, success, failure) {
if (cachedData.length > 0) {
success({ results: filterResults(params.data.q) });
} else {
fetch("https://submit.dese.gov.au/ControlPanel/File.php?F=F_LbC2C0OmXT7JG1k")
.then(response => response.json())
.then(data => {
cachedData = data.results;
success({ results: filterResults(params.data.q) });
})
.catch(failure);
}
},
processResults: function (data) {
return data;
}
}
});

function filterResults(term) {
if (!term) return cachedData;
return cachedData.filter(item =>
item.text.toLowerCase().includes(term.toLowerCase())
);
}

});

 


That’s brilliant - thanks verry much ​@Tom_1842 😊

Now I just gotta add an unload function to save the selected option on submit...I’m sure I saw a post about that somewhere….🤔


Hmm, ok - so it’s clearing the field on form submit. So if it’s a required response, which it is, then the form never submits with the data.
 

Input/select:

 After submit button is hit:


Any idea why it’s removing the selected option?


Right, none of the Multiple Choice answers are actually being selected, so Force Choice won't work, and the selection won't be saved to the dataset. You could save the selection to an Embedded Data field and select a MC answer option with setChoiceValue, but I think you probably want to use a Text Entry question for this. Try adding a Text Entry question to the survey and then adding the below to it's JavaScript. It creates a select element, appends it to the Text Entry question, hides the Text Entry question, initializes select2 on the new select element, and then updates the value of the Text Entry with the selection from the select2 element. Supports Force Choice and back button:

Qualtrics.SurveyEngine.addOnReady(function() {
var qid = this.questionId;
var selectElement = "<select id='s1'><option></option></select>";

// Insert Select2 element and hide the original input
jQuery(selectElement).insertAfter("#" + qid + " .InputText");
jQuery("#" + qid + " .InputText").hide();

let cachedData = [];

// Select2
jQuery("#s1").select2({
ajax: {
transport: function(params, success, failure) {
if (cachedData.length > 0) {
success({ results: filterResults(params.data.q) });
} else {
fetch("https://submit.dese.gov.au/ControlPanel/File.php?F=F_LbC2C0OmXT7JG1k")
.then(response => response.json())
.then(data => {
cachedData = data.results;
success({ results: filterResults(params.data.q) });
})
.catch(failure);
}
},
processResults: function(data) {
return data;
}
}
});

function filterResults(term) {
if (!term) return cachedData;
return cachedData.filter(item =>
item.text.toLowerCase().includes(term.toLowerCase())
);
}

// Update Text Input when selection changes
jQuery("#s1").on('change', function() {
var selectedText = jQuery("#s1 option:selected").text();
jQuery("#" + qid + " .InputText").val(selectedText);
});

// Restore previous selection if available
var previousValue = jQuery("#" + qid + " .InputText").val();
if (previousValue) {
// Add the previous value as an option and select it
var option = new Option(previousValue, previousValue, true, true);
jQuery("#s1").append(option).trigger('change');
}
});

 


Ok - that makes more sense. I was wondering why it wasn’t taking the data, but the new code works great! And saves the data to the appropriate field. It works 100% - thank you so much ​@Tom_1842 💥😎