1

I have a dropdown created with select2 (v4.0.13 and I can not change it) using AJAX requests on a form where the user can search for things. The page is built with Thymeleaf and when the view is reloaded the dropdown value is lost.

Following the recommendation of the documentation itself when you deal with AJAX values, I have writed this code:

let selectedOption = $('#select2-id');
$.ajax({
   type: 'GET',
   dataType: 'json',
   url: baseAjaxUrl + '/api_endpoint?q=' + myVar,
}).then(function (data) {
   if (data.length !== 0) {
       let optionValues = data[0];
       let option = new Option(optionValues.name, optionValues.id, true, true);
       selectedOption.append(option).trigger('change.select2');
       selectedOption.trigger({
           type: 'select2:select',
           params: {data: optionValues}
       });
   }
});

Now, when the view is reloaded the dropdown has the value but does not show its text. An x appears to remove it and if you hover the mouse over it in the tooltip the text that should be displayed in the dropdown appears.

In the <span> generated by select2 I can see the title attribute with the value that should be displayed:

<span class="select2-selection__rendered" id="select2-anId-container" role="textbox" aria-readonly="true" title="The text that should be displayed">
    <span class="select2-selection__clear" title="Remove all items" data-select2-id="20">×</span>
</span>

The select2 is initialised as follows:

$('#select2-id').select2({
   ajax: {
       url: baseAjaxUrl + '/api_endpoint',
       dataType: 'json',
       delay: 180,
       data: function (parameters) {
           return {
               q: parameters.term,
               page: parameters.page
           };
       },
       processResults: function (data, page) {
           return {
               results: data
           };
       }
   },
   placeholder: {
       id: "-1",
       text: "Select an item"
   },
   allowClear: true,
   escapeMarkup: function (markup) {
       return markup;
   },
   minimumInputLength: 5,
   templateResult: formatItem,
   templateSelection: formatItemSelection,
   theme: "bootstrap",
   width: myCustomWidth
});

What is the problem or what have I done wrong?

Greetings.

MinionAttack
  • 513
  • 1
  • 11
  • 26
  • Why are you triggering `.trigger('change.select2');` and not `.trigger('change');` ? – angel.bonev Jun 21 '22 at 11:13
  • 2
    @angel.bonev to limit the scope, it's explained here: https://select2.org/programmatic-control/events#limiting-the-scope-of-the-change-event – MinionAttack Jun 21 '22 at 11:15
  • So it's purposefully. Can you provide the part where you `Set up the Select2 control` – angel.bonev Jun 21 '22 at 11:20
  • @angel.bonev I've updated my question with the code. – MinionAttack Jun 21 '22 at 11:32
  • 2
    wow alot of options, you can try removing some of them an check when the problem will desapear. My wild guess is `templateResult` or `templateSelection` – angel.bonev Jun 21 '22 at 11:40
  • This answer on a different question helped me with a simulair issue on filling select2 with existing value https://stackoverflow.com/a/27964808/3653304 – Ralan Jun 21 '22 at 15:02
  • @Ralan Thank you for your reply. I have tried those options but unfortunately they did not work for me. – MinionAttack Jun 21 '22 at 15:13

1 Answers1

1

After finding this answer, my problem was that when selecting an option, templateSelection is used. Checking the function I realised that the object I receive has the fields id and name. The object that handles select2 also has the fields id and name but it has another one, text, and this is the one it uses to show the value!

So in the function I use for templateSelection I have to do:

if (data.text === "") {
   data.text = data.name;
}
... other stuff ...
return data.text;

Done!

MinionAttack
  • 513
  • 1
  • 11
  • 26