We've found several examples of pre-populating selected option for Select2, however none of them we could find deal with formatted list and selection options. We have a JS fiddle at https://jsfiddle.net/gpsx62de/26/ that illustrates the issue. In that fiddle, you can type and L or whatever into the select search and the data is returned, the list is formatted, and if you select something, the selection is formatted.
However if you click the button in that JS Fiddle which is intended to simulate pre-population per https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2 the data is returned (you can uncomment the console.log to see it), but the formatted selection shows undefined for the intended values. Does anyone know of a way to get the formatted values for pre-populated data to display correctly?
// Set up the Select2 control
$('#mySelect2').select2({
ajax: {
url: '/api/students'
}
});
// Fetch the preselected item, and add to the control
var studentSelect = $('#mySelect2');
$.ajax({
type: 'GET',
url: '/api/students/s/' + studentId
}).then(function (data) {
// create the option and append to Select2
var option = new Option(data.full_name, data.id, true, true); //**** DOES IT MATTER WHAT IS PASSED HERE BECAUSE WE ARE NOT DISPLAY THE OPTION TEXT?? ***
studentSelect.append(option).trigger('change');
// manually trigger the `select2:select` event
studentSelect.trigger({
type: 'select2:select',
params: {
data: data //**** THIS DOES NOT SEEM TO SUPPORT FORMATTED SELECTIONS, SO HOW CAN THIS BE DONE? ***
}
});
});
var initial_creditor_id = "3"; $(". creditor_select2"). select2({ ajax: { url: "/admin/api/transactions/creditorlist", dataType: 'json', delay: 250, data: function (params) { return { q: params. term, c_id: initial_creditor_id, page: params.
Select2 requires that the id property is used to uniquely identify the options that are displayed in the results list. If you use a property other than id (like pk ) to uniquely identify an option, you need to map your old property to id before passing it to Select2.
By default, Select2 will attach the dropdown to the end of the body and will absolutely position it to appear above or below the selection container. Select2 will display the dropdown above the container if there is not enough space below the container, but there is enough space above it.
Select2 will register itself as a jQuery function if you use any of the distribution builds, so you can call .select2() on any jQuery selector where you would like to initialize Select2.
The problem is in format_selection function. The format of the object it receives depends on how it was created. When you use new Option(text, value)
it receives only the properties of this Option object, not your original object containing all user info.
A workaround is to check of either possible values in the fuction:
function format_selection(obj) {
let name = obj.name || obj.element.text;
let email = obj.email || obj.element.email;
return $(`<div><b>${name}</b></div><div>(${email})</div>`);
}
For this to work you should append the de property on you Option object:
var option = new Option(data.name, data.id, true, true);
option.email = data.email;
$('#sel').append(option).trigger('change');
The problem, in https://jsfiddle.net/gpsx62de/26/ is with the
function format_selection(obj) {
// Just add this to see the obj
console.log(obj);
return $(`<div><b>${obj.text}</b></div><div>(${obj.id})</div>`);
}
The obj
object just contains the Option class data, so:
id: "1",
selected: true,
text: "Leanne Graham",
title: ""
So you have to find a way to pass "data.email" to the "format_selection" method
EDIT
This could be a solution
$('#btn').on('click', function() {
$.ajax({
type: 'GET',
url: 'https://jsonplaceholder.typicode.com/users/1'
})
.then(function(data) {
console.log(data)
// create the option and append to Select2
$('#sel').append($('<option />') // Create new <option> element
.val(data.id) // Set value
.text(data.name) // Set textContent
.prop('selected', true)
.attr('data-name', data.name) // Don't know why the .data(key, value) isn't working...
.attr('data-email', data.email))
.trigger('change');
}); //then
}); //click
And
function format_selection(obj) {
return $(`<div><b>${obj.element.dataset.name}</b></div><div>(${obj.element.dataset.email})</div>`);
}
This is the fiddle https://jsfiddle.net/947jngtu/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With