How to maintain the user's sorted order for further manipulations

i have 2 menus, one of which is in select 2 (champions) (max 3 selections)
The options that are enabled in the champions menu change upon selecting a different option in menu 1 (through class sharing of the option elements within the primarychange() function)
furthermore, any selected options in the select2 menu that dont share a class are removed. I use arrays to maintain the order in the selected options.
my question relates to the drop and drag (sort) feature. Whenever a user changes the order, if they then select a different option in menu 1, the select2 menu rearranges the options alphabetically. I want to keep the order in which the user sorted them. I’m guessing select2 sort does not store the rearranged order for me. How do i fix this?

select id=‘first menu’ onchange=“primarychange()”>
option id=“nopreference” value=“0”>no pref
option id=“1a” class=“blue” value=“1”>option 1
option id=“2a” class=“red” value=“2”>option 2
option id=“3a” class=“purple” value=“3”>option 3
option id=“4a” class=“beige” value=“4”>option 4
option id=“5a” class=“yellow” value=“5”>option 5t
option id=“6a” value=“6”>violetl
/select>

select id=‘fruits’>
select id=‘champions’ style=“width: 280px;” multiple=“multiple”>
option id=“1b” class=“purple” value=“1”>blue
option id=“2b” class=“red” value=“2”>red
option id=“3b” class=“yellow” value=“3”>purple
option id=“4b” class=“red” value=“4”>yellow
option id=“5b” class=“purple” value=“5”>amber
/select>

The scripts included in the header are:
script src="local path\jquery-3.6.4.js>
script src=“local path\select2.min.js”>
script src=“local path/jquery-ui.js”>
script> src=“local path\en.min.js”>

the code relevant to the select2 menu:

script>
function destroySelect2() {
$("#champions").select2(‘destroy’);
}

function reviveSelect2() {
$("#champions").select2({
maximumSelectionLength: 3,
language: “fr”,
sorter: function(data) {
var enabled = data.filter(function(d) {
return !d.disabled;
});
var disabled = data.filter(function(d) {
return d.disabled;
});
return enabled.concat(disabled);
}
});
$(“ul.select2-selection__rendered”).sortable({
containment: ‘parent’,
stop: function(event, ui) {
var arr = Array.from($(event.target).find(‘li:not(.select2-search)’).map(function () {
return {name: $(this).data(‘data’).text, value: $(this).data(‘data’).id };
}));
var select = $(event.target).parents(‘span.select2-container’).prev(‘select’);
// sort the options based on arr
$(‘champions’).find(‘option’).each(function (i, option) {
option.value = arr[i].value;
$(option).text(arr[i].name);
c
});
}});
}

$(document).ready(function() {
  reviveSelect2();
});

$("#champions").on("select2:select", function(evt) {
  var element = evt.params.data.element;
  var $element = $(element);

  if ($("#champions").find(":selected").length > 1) {
    var $second = $("#champions").find(":selected").eq(-2);
    $element.detach();
    $second.after($element);
  } else {
    $element.detach();
    $("#champions").prepend($element);
  }

  $("#champions").trigger("change");
  var orderedArray= $("#champions").serializeArray;
});

</script

What’s the solution? Another quick question: where do i add this code:

$(’.select2-search__field’).attr(‘maxlength’, 14);

to set a maximum length for typing in the search box of the champions menu? I keep getting syntax errors or it’s not functional.

Go easy on me, i started coding this week.

edit, I found solution. It involves updating the values within the stop function:

$("ul.select2-selection__rendered").sortable({

containment: ‘parent’,
stop: function(event, ui) {
var arr = $(this).find(‘li:not(.select2-search)’).map(function () {
return {name: $(this).data(‘data’).text, value: $(this).data(‘data’).id };
}).get();

var select = $(event.target).parents('span.select2-container').prev('select');
for (var i = 0; i < arr.length; i++) {
  var option = select.find('option[value="' + arr[i].value + '"]');
  option.val(arr[i].value);
  option.text(arr[i].name);
}

}
})
};

My initial idea was :
$(“ul.select2-selection__rendered”).sortable({
containment: ‘parent’,
stop: function(event, ui) {
var arr = $(this).find(‘li:not(.select2-search)’).map(function () {
return {name: $(this).data(‘data’).text, value: $(this).data(‘data’).id };
}).get();

var select = $(event.target).parents('span.select2-container').prev('select');
for (var i = 0; i < arr.length; i++) {
  var option = select.find('option[value="' + arr[i].value + '"]');
  
  option.detach(); //
  option.val(arr[i].value); // 
  option.text(arr[i].name); // 
  select.append(option); // 
}

}
});

The problem with the latter method is that when the menu is changed dynamically after sorting, the detach command creates a problem, it removes new selections by the user from the menu!

So in other words, the first code updates the order of the items when sorting is complete. This can be useful if the order is relevant and you don’t want them to jump back alphabetically.

Just a quick update that select2 and all these plugins are hot garbage unless it fits your exact use case. I just started from scratch and built shit myself.